• SPGridView


    http://www.cnblogs.com/enjoyment的文章,自己整理后:

    SPGridView是MOSS内置控件中少数能脱离SharePoint List等内置数据源使用的控件, 它继承自System.Web.UI.WebControls.GridView, 但是使用SPGridView时必须手动把AutoGenerateColumns设成false.

    1. 先创建一个ASP.NET Web Application(ASP.NET Web应用程序)项目.
    CreateProject
    该项目模板已经包含在VS2005 SP1中, 如果你不打算安装SP1, 就需要先更新KB915364, 再安装 Microsoft Visual Studio Web Application Projects.

    2. 把引用中无用System.Web.Mobile等Assembly都去掉, 加入Microsoft.SharePoint (找不到的人去找块豆腐撞死好了). 再建个名为 ~masterurl 的目录, 放入一个default.master.
    AddMaster

    default.master的代码如下

       1: <%@ Master Language="C#" %>
       2: <html>
       3: <head runat="server">
       4:     <asp:contentplaceholder id="PlaceHolderAdditionalPageHead" runat="server"></asp:contentplaceholder>
       5: </head>
       6: <body>
       7:     <form id="form1" runat="server">
       8:         <asp:ContentPlaceHolder ID="PlaceHolderPageTitleInTitleArea" runat="server">
       9:         </asp:ContentPlaceHolder>
      10:         <asp:ContentPlaceHolder ID="PlaceHolderMain" runat="server">
      11:         </asp:ContentPlaceHolder>
      12:     </form>
      13: </body>
      14: </html>

    项目中的那个instnwnd.sql是取自Microsoft提供的SQL Server 2000 Sample Databases里的Northwind数据库的脚本.使用脚本建立Northwind数据库. 并将连接字符串加入web.config.

    3. 建立数据访问类NorthwindData.cs. 后面我们将使用ObjectDataSource组件来为SPGridView提供数据.

       1: using System;
       2: using System.Data;
       3: using System.Data.SqlClient;
       4: using System.Configuration;
       5:  
       6: namespace SPGridView_Demo
       7: {
       8:     public class NorthwindData
       9:     {
      10:         private static string connectionString = null;
      11:  
      12:         public NorthwindData()
      13:         {
      14:             if(string.IsNullOrEmpty(connectionString))
      15:             {
      16:                 connectionString = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
      17:             }
      18:         }
      19:  
      20:         public int GetProductCount()
      21:         {
      22:             int count = 0;
      23:             string commandText = "SELECT COUNT(ProductId) FROM dbo.Products";
      24:             SqlConnection connection = new SqlConnection(connectionString);
      25:             SqlCommand command = new SqlCommand(commandText, connection);
      26:             connection.Open();
      27:             count = Convert.ToInt32(command.ExecuteScalar());
      28:             connection.Close();
      29:             return count;
      30:         }
      31:  
      32:         public DataTable GetProductList(string sortExpression)
      33:         {
      34:             DataTable dt = new DataTable();
      35:             string commandText = "SELECT ProductId, ProductName, p.CategoryId, p.UnitPrice, p.Discontinued, c.CategoryName FROM dbo.Products p INNER JOIN dbo.Categories c ON p.CategoryId = c.CategoryId ORDER BY {SORT}";
      36:  
      37:             if(sortExpression == null || sortExpression.Trim() == string.Empty)
      38:             {
      39:                 sortExpression = "ProductId";
      40:             }
      41:  
      42:             commandText = commandText.Replace("{SORT}", sortExpression);
      43:             SqlConnection connection = new SqlConnection(connectionString);
      44:             SqlDataAdapter adapter = new SqlDataAdapter(commandText, connection);
      45:             connection.Open();
      46:             adapter.Fill(dt);
      47:             connection.Close();
      48:             return dt;
      49:         }
      50:  
      51:         public DataTable GetProductList(int startRowIndex, int maximumRows, string sortExpression)
      52:         {
      53:             DataTable dt = new DataTable();
      54:             string commandText = "SELECT * FROM (SELECT ProductId, ProductName, p.CategoryId, UnitPrice, p.Discontinued, c.CategoryName, ROW_NUMBER() OVER (ORDER BY {SORT}) AS RowNumber FROM dbo.Products p INNER JOIN dbo.Categories c ON p.CategoryId = c.CategoryId) a WHERE RowNumber BETWEEN @StartRowIndex + 1 AND @StartRowIndex + @MaximumRows";
      55:  
      56:             if(sortExpression == null || sortExpression.Trim() == string.Empty)
      57:             {
      58:                 sortExpression = "ProductId";
      59:             }
      60:  
      61:             commandText = commandText.Replace("{SORT}", sortExpression);
      62:             SqlConnection connection = new SqlConnection(connectionString);
      63:             SqlDataAdapter adapter = new SqlDataAdapter(commandText, connection);
      64:             adapter.SelectCommand.Parameters.Add(new SqlParameter("@StartRowIndex", startRowIndex));
      65:             adapter.SelectCommand.Parameters.Add(new SqlParameter("@MaximumRows", maximumRows));
      66:             connection.Open();
      67:             adapter.Fill(dt);
      68:             connection.Close();
      69:             return dt;
      70:         }
      71:     }
      72: }

    4. 创建 SPGVP1.aspx

    CreateP1-1 CreateP1-2

    我们先试着绑些数据给SPGridView, 再发布到MOSS里看看效果吧.
    代码:

       1: <%@ Page Language="C#" MasterPageFile="~masterurl/default.master" %>
       2:  
       3: <%@ Register Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls" TagPrefix="cc1" %>
       4: <asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
       5: </asp:Content>
       6: <asp:Content ID="Content2" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
       7: </asp:Content>
       8: <asp:Content ID="Content3" ContentPlaceHolderID="PlaceHolderMain" runat="server">
       9:     <cc1:SPGridView ID="SPGridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1">
      10:         <Columns>
      11:             <cc1:SPBoundField DataField="ProductId" HeaderText="Product ID" SortExpression="ProductId" />
      12:             <asp:HyperLinkField DataTextField="ProductName" DataNavigateUrlFields="ProductId" DataNavigateUrlFormatString="#{0}" HeaderText="Product Name" SortExpression="ProductName" />
      13:             <cc1:SPBoundField DataField="ProductName" HeaderText="Product Name" SortExpression="ProductName" />
      14:             <cc1:SPBoundField DataField="CategoryName" HeaderText="Category" SortExpression="CategoryName" />
      15:             <asp:BoundField DataField="UnitPrice" DataFormatString="${0:F2}" HeaderText="Unit Price" SortExpression="UnitPrice" />
      16:             <asp:TemplateField HeaderText="Orderable" SortExpression="Discontinued">
      17:                 <itemtemplate>
      18:                 <asp:Label id="lblDiscontinued" runat="server" text='<%# Convert.ToBoolean(Eval("Discontinued")) ? "Yes" : "No" %>'></asp:Label></itemtemplate>
      19:             </asp:TemplateField>
      20:         </Columns>
      21:     </cc1:SPGridView>
      22:     <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetProductList" TypeName="SPGridView_Demo.NorthwindData" SortParameterName="sortExpression"></asp:ObjectDataSource>
      23: </asp:Content>

    效果:
    P1-1

    然后我们给Product Name列加入项菜单吧, 我们计划给它加入2个菜单项, 1个是链接型View Deltail, 另1个是回发型Order Now. 觉得不过瘾再加个带!号的Order Now, 用于区别Unit Price高于$40的产品好了.

    我们把Product Name列那行代码 

    <asp:HyperLinkField DataTextField="ProductName" DataNavigateUrlFields="ProductId" DataNavigateUrlFormatString="#ProductDetail-{0}" HeaderText="Product Name" SortExpression="ProductName" />
    改成
    <cc1:SPMenuField HeaderText="Product Name" MenuTemplateId="mtProduct" SortExpression="ProductName" TextFields="ProductName" TokenNameAndValueFields="PID=ProductId,PNAME=ProductName" NavigateUrlFields="ProductId" NavigateUrlFormat="#ProductDetail-{0}" />
    基中MenuTemplateId属性指定了一个菜单模板(MenuTemplate), 菜单模板也是一个SharePoint控件类.将下面的代码加到SPGridView代码之外.
    <cc1:MenuTemplate ID="mtProduct" runat="server">
        <cc1:MenuItemTemplate ID="mitView" runat="server" Text="View Detail" ClientOnClickNavigateUrl="#ProductDetail-%PID%" />
        <cc1:MenuItemTemplate ID="mitOrder" runat="server" Text="Order Now" />
        <cc1:MenuItemTemplate ID="mitOrderWarn" runat="server" Text="Order Now" ImageUrl="/_layouts/images/exclaim.gif" />
    </cc1:MenuTemplate>

    注意: ID为mitView的菜单项模板使用了ClientOnClickNavigateUrl属性来指定此菜单项的连接, 它类似与HyperLinkField的DataNavigateUrlFormatString属性, 但是变量标识是%Alias%, 而不是{index}或列名. 这里的数据别名(Alias)是在调用此菜单模板的SPMenuField的TokenNameAndValueFields指定的, 格式为 "别名1=列名1,别名2=列名2,...".
    特别注意: 我们使用了PNAME 代表ProductName的数据, 如果数据里包含单/双引号等字符, 会导致菜单项失灵. 因为最终控件生成的HTML代码将是 location.href='XXXXX' 或 ''__doPostBack('YYYYYY')". 哈! 像JS注入吧~.

    然后我们在SPGridVIew的OnRowDataBound事件中写些判断代码来控制不同情况下菜单模板的显示. 我们不打算让用户订购Discontinued的产品, 并在订购菜单项中使用!号图标提示该产品单价超过了$40.

    protected void SPGridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if(e.Row.RowType == DataControlRowType.DataRow)
    {
    Microsoft.SharePoint.WebControls.Menu menu = e.Row.Cells[1].Controls[0] as Microsoft.SharePoint.WebControls.Menu;
    if(menu != null)
    {
    bool discontinued = Convert.ToBoolean(DataBinder.Eval(e.Row.DataItem, "Discontinued"));
    decimal unitPrice = Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "UnitPrice"));
    if(discontinued)
    {
    menu.HiddenMenuItems.Add(this.mitOrder);
    menu.HiddenMenuItems.Add(this.mitOrderWarn);
    }
    if(unitPrice >= 40m)
    {
    menu.HiddenMenuItems.Add(this.mitOrder);
    }
    else
    {
    menu.HiddenMenuItems.Add(this.mitOrderWarn);
    }
    }
    }
    }

    让我们来看看现在实现了的效果.
    P1-2
    P1-3
    P1-4

    我们还需要给Order Now菜单项添加回发行为.

    protected override void OnInit(EventArgs e)
    {
    base.OnInit(e);
    this.mitOrder.ClientOnClickUsingPostBackEventFromControl(this.SPGridView1, "Order:%PID%");
    this.mitOrderWarn.ClientOnClickUsingPostBackEventFromControl(this.SPGridView1, "Order:%PID%");
    }
    这样我们的Order Now菜单项的点击行为会变成 __doPostBack('ctl00$PlaceHolderMain$SPGridView1','Order:22') 的样子. 现在我们加入代码来响应这些回发操作.
    private void Order(string pid)
    {
    Response.Write(pid + " is ordered.");
    }
    protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
    {
    base.RaisePostBackEvent(sourceControl, eventArgument);
    if(eventArgument == null || eventArgument.Trim() == string.Empty)
    {
    return;
    }
    if(eventArgument.Contains(":"))
    {
    int posIndex = eventArgument.IndexOf(":");
    string commandName = eventArgument.Substring(0, posIndex);
    string argument = eventArgument.Remove(0, posIndex + 1);
    switch(commandName)
    {
    case "Order":
    this.Order(argument);
    break;
    }
    this.SPGridView1.DataBind();
    }
    }
     
    Isn't it amazing?
     
    完整代码:
    <%@ Page Language="C#" MasterPageFile="~masterurl/default.master" %>
    <%@ Register Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls" TagPrefix="cc1" %>
    <script runat="server">
    
       1:  
       2:     private void Order(string pid)
       3:     {
       4:         Response.Write(pid + " is ordered.");
       5:     }
       6:  
       7:     protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
       8:     {
       9:         base.RaisePostBackEvent(sourceControl, eventArgument);
      10:  
      11:         if(eventArgument == null || eventArgument.Trim() == string.Empty)
      12:         {
      13:             return;
      14:         }
      15:  
      16:         if(eventArgument.Contains(":"))
      17:         {
      18:             int posIndex = eventArgument.IndexOf(":");
      19:             string commandName = eventArgument.Substring(0, posIndex);
      20:             string argument = eventArgument.Remove(0, posIndex + 1);
      21:  
      22:             switch(commandName)
      23:             {
      24:                 case "Order":
      25:                     this.Order(argument);
      26:                     break;
      27:             }
      28:  
      29:             this.SPGridView1.DataBind();
      30:         }
      31:     }
      32:     
      33:     protected override void OnInit(EventArgs e)
      34:     {
      35:         base.OnInit(e);
      36:  
      37:         this.mitOrder.ClientOnClickUsingPostBackEventFromControl(this.SPGridView1, "Order:%PID%");
      38:         this.mitOrderWarn.ClientOnClickUsingPostBackEventFromControl(this.SPGridView1, "Order:%PID%");
      39:     }
      40:     
      41:     protected void SPGridView1_RowDataBound(object sender, GridViewRowEventArgs e)
      42:     {
      43:         if(e.Row.RowType == DataControlRowType.DataRow)
      44:         {
      45:             Microsoft.SharePoint.WebControls.Menu menu = e.Row.Cells[1].Controls[0] as Microsoft.SharePoint.WebControls.Menu;
      46:  
      47:             if(menu != null)
      48:             {
      49:                 bool discontinued = Convert.ToBoolean(DataBinder.Eval(e.Row.DataItem, "Discontinued"));
      50:                 decimal unitPrice = Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "UnitPrice"));
      51:  
      52:                 if(discontinued)
      53:                 {
      54:                     menu.HiddenMenuItems.Add(this.mitOrder);
      55:                     menu.HiddenMenuItems.Add(this.mitOrderWarn);
      56:                 }
      57:  
      58:                 if(unitPrice >= 40m)
      59:                 {
      60:                     menu.HiddenMenuItems.Add(this.mitOrder);
      61:                 }
      62:                 else
      63:                 {
      64:                     menu.HiddenMenuItems.Add(this.mitOrderWarn);
      65:                 }
      66:             }
      67:         }
      68:     }
    </script> <asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server"> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="PlaceHolderMain" runat="server"> <cc1:SPGridView ID="SPGridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" OnRowDataBound="SPGridView1_RowDataBound"> <Columns> <cc1:SPBoundField DataField="ProductId" HeaderText="Product ID" SortExpression="ProductId" /> <cc1:SPMenuField HeaderText="Product Name" MenuTemplateId="mtProduct" SortExpression="ProductName" TextFields="ProductName" TokenNameAndValueFields="PID=ProductId,PNAME=ProductName" NavigateUrlFields="ProductId" NavigateUrlFormat="#ProductDetail-{0}" /> <cc1:SPBoundField DataField="ProductName" HeaderText="Product Name" SortExpression="ProductName" /> <cc1:SPBoundField DataField="CategoryName" HeaderText="Category" SortExpression="CategoryName" /> <asp:BoundField DataField="UnitPrice" DataFormatString="${0:F2}" HeaderText="Unit Price" SortExpression="UnitPrice" /> <asp:TemplateField HeaderText="Orderable" SortExpression="Discontinued"> <itemtemplate> <asp:Label id="lblDiscontinued" runat="server" text='<%# Convert.ToBoolean(Eval("Discontinued")) ? "Yes" : "No" %>'></asp:Label> </itemtemplate> </asp:TemplateField> </Columns> </cc1:SPGridView> <cc1:MenuTemplate ID="mtProduct" runat="server"> <cc1:MenuItemTemplate ID="mitView" runat="server" Text="View Detail" ClientOnClickNavigateUrl="#ProductDetail-%PID%" /> <cc1:MenuItemTemplate ID="mitOrder" runat="server" Text="Order Now" /> <cc1:MenuItemTemplate ID="mitOrderWarn" runat="server" Text="Order Now" ImageUrl="/_layouts/images/exclaim.gif" /> </cc1:MenuTemplate> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetProductList" TypeName="SPGridView_Demo.NorthwindData" SortParameterName="sortExpression"></asp:ObjectDataSource> </asp:Content>
    Isn't it amazing?
     
    个人修改后的完整代码(无回发部分):
     

    Code

    x后台部分:

    Code


    Have you ever wanted to create a custom SharePoint menu using a MenuItemTemplate in a delegate control and handle a post back, for example in the welcome menu delegate control? Using the ClientOnClickScript and ClientOnClickScript properties is fairly easy, but wiring up the ClientOnClickUsingPostBackEvent can be a little tricky. To get around this I subclassed the MenuItemTemplate with an event to which you can subscribe. The menu item will target itself for postback, unless you specify otherwise – or it can be used as a normal menuitem by not subscribing to the event. Here is the code for the class:

    Code
    Then simply instantiate an ObjectDataSource object that points to the example data class in the CreateChildControl() method of the web part:


    Code

    如何添加回发



    最近做的项目需要使用SPGridView,并在SPGridView使用下拉菜单。

    参考了一下这篇博客:

    http://www.cnblogs.com/enjoyment/archive/2008/12/28/1364142.html

    关于如何通过MenuItemTemplate的ClientOnClickNavigateUrl属性来指定此菜单项的连接,这篇文章中写得很清楚,我就不多说了。

    至于如何处理菜单项的回发行为,我就看得有点晕了。后来又参考了一下这篇文章:

    http://www.thesug.org/blogs/patrickr/Lists/Posts/Post.aspx?List=8afc69af%2Df9fc%2D4786%2D816f%2D6419264c42da&ID=18

    总算是做出来了,下面总结一下:

    1.首先需要定义一个类,该类继承自MenuItemTemplate,并实现 IPostBackEventHandler接口
    代码如下:


    class PostBackMenuItemTemplate : MenuItemTemplate, IPostBackEventHandler
    {
         
    protected override void
     EnsureChildControls()
        {
            
    if (!this
    .ChildControlsCreated)
            {
                
    base
    .EnsureChildControls();
                
    if (string.IsNullOrEmpty(this
    .ClientOnClickUsingPostBackEvent))
                {
                    
    this.ClientOnClickUsingPostBackEventFromControl(this"%ItemID%");//此处的"%ItemID%" 要与后面的  menuCol.TokenNameAndValueFields = "ItemID=ID"; 相对应

                }
            }
        }

        
    public void RaisePostBackEvent(string
     eventArgument)
        {
            MenuItemEventHandler handler 
    = this
    .OnPostBack;
            
    if (handler != null
    )
            {
                handler(eventArgument);
            }
        }

        
    public event
     MenuItemEventHandler OnPostBack;
    }

    public delegate void MenuItemEventHandler(string
     id);
    2.下面是一个例子演示了如何使用

    在下面的代码中,为SPGridView添加了一个菜单列,菜单中包含一个菜单项,点击后由 mit_OnPostBack 方法处理回发


    protected void initSPGridView()
    {

      SPMenuField menuCol 
    = new
     SPMenuField();
            menuCol.TextFields 
    = "用品名称"
    ;
            menuCol.HeaderText 
    = "用品名称"
    ;
            menuCol.MenuTemplateId 
    = "menu"
    ;
            menuCol.TokenNameAndValueFields 
    = "ItemID=ID"//此处要与前面的 this.ClientOnClickUsingPostBackEventFromControl(this, "%ItemID%"); 相对应

            MenuTemplate mt = new MenuTemplate();
            mt.ID 
    = "menu"
    ;
            PostBackMenuItemTemplate mit 
    = new
     PostBackMenuItemTemplate();
            mit.ClientOnClickPostBackConfirmation 
    = "你确定要删除吗?"
    ;
            mit.Text 
    = "删除"
    ;
            mit.ID 
    = "menu1";//必须要给ID赋值,否则会出错

            mit.OnPostBack+=new MenuItemEventHandler(mit_OnPostBack);
            mt.Controls.Add(mit);
            
    this
    .Controls.Add(mt);
            SPGridView1.Columns.Add(menuCol);

    }
    处理MenuItemTemplate的回发

     void mit_OnPostBack(string id)
        {
            
    //此处的id就是菜单对应的那个列表项的ID了,可以通过ID找到列表项并进行操作。在这个例子中,我只是用一个label来显示该ID

            Label1.Text = id;
        }

  • 相关阅读:
    SQLServer中查询的数字列前面补0返回指定长度的字符串
    Http Module 介绍
    SQLite中使用时的数据类型注意
    SQLite中的PRAGMA语句攻略
    Sqlite中使用rowid来表示行号,用于分页。
    Sqlite基础及其与SQLServer语法差异
    SQLite中的日期基础
    Asp.net页面无刷新请求实现
    CSS3实现的渐变按钮,在IE7、IE6下的滤镜使用。
    如何给网站页面添加图标?
  • 原文地址:https://www.cnblogs.com/ceci/p/1536547.html
Copyright © 2020-2023  润新知