今年一直在为MOSS 2007写自制ASP.NET程序, 为了让程序的样式更通用, 更配合MOSS自带的风格, 我花不了少时间调整样式, 建立公用的CSS和JS.

一个偶然的机会, 我从一大堆"无用的"SharePoint内置控件中找到一个可以用的控件, 就是SPGridView. SPGridView提供了MOSS的列表样式, 给我省了不少功夫. 虽然SPGridView跟MOSS列表页里用的ListViewWebPart长得一模一样, 但是ListViewWebPart根本没用到SPGridView, 所以MOSS列表页里那个漂亮的工具条你就别想了 呵呵.

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

1. 先创建一个ASP.NET Web Application(ASP.NET Web应用程序)项目.

该项目模板已经包含在VS2005 SP1中, 如果你不打算安装SP1, 就需要先更新KB915364, 再安装 Microsoft Visual Studio Web Application Projects.

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

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

我们先试着绑些数据给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>

效果:

然后我们给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);}                }}
}

让我们来看看现在实现了的效果.


我们还需要给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>

转载于:https://www.cnblogs.com/ericfine/archive/2008/10/22/1316431.html

SPGridView 研究笔记 Part 1 - 基础和项菜单相关推荐

  1. bootstrap基础学习【菜单、按钮、导航】(四)

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>boo ...

  2. 七彩虹主板进BIOS设置和打开启动项菜单快捷键

    进BIOS设置:开机时不停地按Del键 打开启动项菜单:开机时不停地按F11键 安装系统可以参考:换装WIN10(windows)那点儿事,换装操作系统一文通,玩转安装操作系统

  3. 华南主板进BIOS设置和打开启动项菜单快捷键

    进BIOS设置:开机时不停地按Del键 打开启动项菜单:开机时不停地按F7键或F11键 实测华南x79主板按的是F7键 安装系统可以参考:换装WIN10(windows)那点儿事,换装操作系统一文通, ...

  4. 用javascript自定义SharePoint文档库/列表项菜单

    本文转自YCC博客 我们在SharePoint中自定义菜单,通常通过带CustomAction 的Feature来实现,比如隐藏一个菜单: <HideCustomAction>   Gro ...

  5. 对齐方式有那些_Excel基础:开始菜单之对齐方式,那些被遗忘的实用功能

    今天小编要分享的Excel基础系列文章是"第三区块-对齐方式".对齐方式主要是出来文字的排版问题,对齐方式包含的所有功能下面思维导图已经列出来.大多数功能都是我们常用的,也是比较简 ...

  6. 成都拓嘉启远:拼多多基础四项优化如何做

    不管是开拼多多店铺还是其它的网店,主图.标题.详情页以及评论区都是店铺的最基础.最根本的优化,这是店铺的重点,所以不能被忽视,如果自己不会做优化,那么需要请专业人士进行优化,毕竟关系到店铺的点击.排名 ...

  7. Excel基础:开始菜单之字体的华丽转身

    点赞再看,养成习惯:老骥伏枥,志在千里. 微信搜索[亦心Excel]关注这个不一样的自媒体人. 本文 GitHub https://github.com/hugogoos/Excel 已收录,包含Ex ...

  8. Excel基础:开始菜单之对齐方式,那些被遗忘的实用功能

    点赞再看,养成习惯:山不在高,有仙则名. 微信搜索[亦心Excel]关注这个不一样的自媒体人. 本文 GitHub https://github.com/hugogoos/Excel 已收录,包含Ex ...

  9. HTML基础6折叠菜单手风琴菜单

    页面主体部分: <body><ul id="menu"><li> <a href="#">一级菜单1</a ...

最新文章

  1. 常引用、常量指针、指针常量、指向常量的常指针、空指针与野指针解释
  2. InfoQ专访网易云陈谔:用微服务体系满足企业数字化转型需求
  3. 181920.net用 文字存档
  4. 数据结构——树、二叉树、森林、哈夫曼树、字符串模式匹配
  5. win7下安装pip——Python的包管理工具
  6. bzoj 2178 圆的面积并 —— 辛普森积分
  7. 几本人工智能入门书籍
  8. php %3ch1%3e字体,phpWebSite搜索模块跨站脚本执行漏洞
  9. mysql系统变量配置文件_MySQL系统变量配置基础
  10. C#调用新浪微博API生成RSS资源文件
  11. AXURE9最全的WEB设计元件库(分享版).rplib
  12. python定时任务_Python定时任务
  13. canal 全量数据
  14. Node.js开发入门—使用http访问外部世界
  15. Anaconda中pkgs文件夹详解
  16. AutoResetEvent 与 ManualResetEvent区别
  17. Socket异步服务器,可以监控客户端的状态,功能有,文字测试,服务端向客户端传输屏幕录像(UDP传输)、监控客户端屏幕(UDP传输),抖动用户窗体、发送文件给用户、扫描客户的C盘目录。
  18. Matlab坐标轴标注和特殊字体
  19. 【Python】-- python与json数据格式的转换
  20. java 级联删除_JavaEE中的级联删除讲解级源码

热门文章

  1. 介绍一个制作情侣网站的方法,无需服务器、域名,基于saas和动态地址
  2. 百度 2019校园招聘 计算机视觉算法研发工程师
  3. 时尚界新宠,高级穿搭1+1
  4. 解读vue-element-admin登录逻辑permission.js
  5. 6个Python童年小游戏,开始敲起来,玩吧!
  6. SQL语句大全大全(经典珍藏版)
  7. python创建员工_python-作业:员工信息表
  8. 智鼎逻辑推理题及答案_经验分享:校招过四关拿offer,助力收割大厂
  9. 【Python机器学习】层次聚类AGNES、二分K-Means算法的讲解及实战演示(图文解释 附源码)
  10. Gorm -- 添加记录