现在的位置: 首页 > 综合 > 正文

扩展GridView控件(索引) – 增加多个常用功能

2013年09月01日 ⁄ 综合 ⁄ 共 13732字 ⁄ 字号 评论关闭
文章目录

文章索引
扩展GridView控件(1) - 鼠标经过行时改变行的样式
扩展GridView控件(2) - 复合排序和排序状态提示
扩展GridView控件(3) - 根据按钮的CommandName设置其客户端属性
扩展GridView控件(4) - 联动复选框(复选框的全选和取消全选)
扩展GridView控件(5) - 固定指定行、指定列
扩展GridView控件(6) - 响应行的单击事件和双击事件
扩展GridView控件(7) - 行的指定复选框选中时改变行的样式
扩展GridView控件(8) - 导出数据源的数据为Excel、Word或Text
扩展GridView控件(9) - 给数据行增加右键菜单
扩展GridView控件(10) - 自定义分页样式
扩展GridView控件(11) - 合并指定列的相邻且内容相同的单元格
注:除了“固定指定行、指定列”仅支持IE外,其它均同时支持IE和FF

控件截图

控件使用
1、鼠标经过行的时候改变该行的样式,鼠标离开行的时候恢复该行的样式
使用方法(设置属性): 
MouseOverCssClass - 鼠标经过行时行的 CSS 类名

2、对多个字段进行复合排序;升序、降序的排序状态提示
使用方法(设置SmartSorting复合属性):
AllowSortTip - 是否启用排序提示
AllowMultiSorting - 是否启用复合排序
SortAscImageUrl - 升序提示图片的URL(不设置则使用默认图片)
SortDescImageUrl - 降序提示图片的URL(不设置则使用默认图片)
SortAscText - 升序提示文本
SortDescText - 降序提示文本

3、根据按钮的CommandName设置其客户端属性
使用方法(设置ClientButtons集合属性):
BoundCommandName - 需要绑定的CommandName
AttributeKey - 属性的名称
AttributeValue - 属性的值(两个占位符:{0} - CommandArgument;{1} - Text)
Position - 属性的值的位置

4、联动复选框(复选框的全选和取消全选)。选中指定的父复选框,则设置指定的所有子复选框为选中状态;取消选中指定的父复选框,则设置指定的所有子复选框为取消选中状态
使用方法(设置CascadeCheckboxes集合属性):
ParentCheckboxID - 模板列中 父复选框ID
ChildCheckboxID - 模板列中 子复选框ID
YYControls.Helper.SmartGridView中的静态方法
List GetCheckedDataKey(GridView gv, int columnIndex)
List GetCheckedDataKey(GridView gv, string checkboxId)

5、固定指定行、指定列,根据RowType固定行,根据RowState固定行
使用方法(设置FixRowColumn复合属性):
FixRowType - 需要固定的行的RowType(用逗号“,”分隔)
FixRowState - 需要固定的行的RowState(用逗号“,”分隔)
FixRows - 需要固定的行的索引(用逗号“,”分隔)
FixColumns - 需要固定的列的索引(用逗号“,”分隔)
TableWidth - 表格的宽度
TableHeight - 表格的高度

6、响应行的单击事件和双击事件,并在服务端处理
使用方法(设置属性):
BoundRowClickCommandName - 行的单击事件需要绑定的CommandName
BoundRowDoubleClickCommandName - 行的双击事件需要绑定的CommandName

7、行的指定复选框选中的时候改变该行的样式,行的指定复选框取消选中的时候恢复该行的样式
使用方法(设置CheckedRowCssClass复合属性):
CheckBoxID - 模板列中 数据行的复选框ID
CssClass - 选中的行的 CSS 类名

8、导出数据源的数据为Excel、Word或Text(应保证数据源的类型为DataTable或DataSet)
使用方法:
为SmartGridView添加的方法
Export(string fileName)
Export(string fileName, ExportFormat exportFormat)
Export(string fileName, ExportFormat exportFormat, Encoding encoding)
Export(string fileName, int[] columnIndexList, ExportFormat exportFormat, Encoding encoding)
Export(string fileName, int[] columnIndexList, string[] headers, ExportFormat exportFormat, Encoding encoding)

9、给数据行增加右键菜单,响应服务端事件或超级链接
使用方法(设置ContextMenus集合属性):
Text - 菜单的文本内容
BoundCommandName - 需要绑定的CommandName
NavigateUrl - 链接的URL
Target - 链接的目标窗口或框架
SmartGridView的属性ContextMenuCssClass - 右键菜单的级联样式表 CSS 类名(右键菜单的结构div ul li a)

10、自定义分页样式。显示总记录数、每页记录数、当前页数、总页数、首页、上一页、下一页、末页和分页按钮
使用方法(设置CustomPagerSettings复合属性):
PagingMode - 自定义分页的显示模式
TextFormat - 自定义分页的文本显示样式(四个占位符:{0}-每页显示记录数;{1}-总记录数;{2}-当前页数;{3}-总页数)

11、合并指定列的相邻且内容相同的单元格
使用方法(设置属性):
MergeCells -  需要合并单元格的列的索引(用逗号“,”分隔)

/*正式版的实现 结束*/
/*测试版的实现 开始*/

控件开发
扩展GridView控件(一)——鼠标经过行时改变行的样式

扩展GridView控件(二)——给字段标题加上排序状态

扩展GridView控件(三)——单击命令按钮弹出确认框

扩展GridView控件(四)——每行复选框的全选与取消全选

扩展GridView控件(五)——固定表头、指定行或指定列

扩展GridView控件(六)——数据行响应鼠标的单击和双击事件

扩展GridView控件(七)——改变通过复选框选中的行的样式

扩展GridView控件(八)——导出为Excel

扩展GridView控件(九)——给数据行增加右键菜单

扩展GridView控件(十)——扩展分页功能

控件截图

控件使用
1、鼠标经过行时改变行的样式
CssClassMouseOver - 鼠标经过行时行的样式的CSS类名

2、给字段标题加上排序状态
设置其SortTip下的4个属性即可
SortAscImage - 升序提示图片
SortAscText - 升序提示文本
SortDescImage - 降序提示图片
SortDescText - 降序提示文本

3、单击命令按钮弹出确认框
设置其ConfirmButtons属性
CommandName - 命令按钮的CommandName属性
ConfirmMessage - 弹出的确认框所显示的文字

4、每行复选框的全选与取消全选
在模板列的头模板处添加一个复选框,在模板列的项模板处添加一个复选框,然后设置控件的CheckboxAlls属性
CheckboxAllID - 模板列全选复选框ID
CheckboxItemID - 模板列项复选框ID

5、固定表头、指定行或指定列
设置其FixRowCol下的6个属性
IsFixHeader - 固定表头否?
IsFixPager - 固定分页行否?
FixRowIndices - 需要固定的行的索引(用逗号“,”分隔)
FixColumnIndices - 需要固定的列的索引(用逗号“,”分隔)
TableWidth - 表格的宽度
TableHeight - 表格的高度
EnableScrollState - 是否保持滚动条的状态

6、数据行响应鼠标的单击和双击事件
RowClickButtonID - 行单击事件所对应的按钮的ID
RowDoubleClickButtonID - 行双击事件所对应的按钮的ID

7、改变通过CheckBox选中的行的样式
CheckBoxID - 模板列的项复选框的ID
CssClassRowSelected - 选中行的样式的CSS类名

8、导出为Excel
在GridView内加一个按钮
CommandName属性设置为“ExportToExcel”
CommandArgument属性的值用“;”做分隔符分为两部分,左边的部分为导出Excel的文件名称,右边的部分为需要隐藏的列的索引(列索引用“,”分开)

9、给数据行增加右键菜单
ItemType - 右键菜单的项的类别(Link,Command,Custom,Separator)
Icon - 文字左边的图标的链接
Text - 菜单的文字
CommandButtonId - 所调用的命令按钮的ID
NavigateUrl - 链接的url
Target - 链接的target(Blank,Self,Top)
Key - 自定义属性key
Value - 自定义属性value

10、扩展分页功能
设置PagingStyle属性为Default
设置GridView的原有属性PageButtonCount,FirstPageText,PreviousPageText,NextPageText,LastPageText,FirstPageImageUrl,PreviousPageImageUrl,NextPageImageUrl,LastPageImageUrl

/*测试版的实现 结束*/

OK
[源码下载]

评论共2页: 1 2 下一页 

Feedback

#1楼 [楼主]   回复  引用  查看    

2007-02-13 13:48 by webabcd

@net
:)

#2楼 [楼主]   回复  引用  查看    

2007-02-13 14:55 by webabcd

听取了Wyssoft的建议
增加了“是否保持滚动条的状态”的功能

文章已经更新,源码晚上传

#3楼 [TrackBack]   回复  引用  查看    

2007-02-23 10:24 by 胡立新

[引用提示]胡立新引用了该文章, 地址: http://www.cnblogs.com/hulixin08/archive/2007/02/23/654063.html

#4楼    回复  引用  查看    

2007-02-25 10:01 by 小庄

发现bug:
1,跳到最后一页,全选执行成功,但页面左下角提示脚本错误。
2,然后再转到其它页,全选功能不正常(只选择了最后一页的记录数)。
建议:
我的数据是用存储过程实现分页的(nettires生成的getpaged方法),gridview认为它只有一页,怎么用你的分页样式呢?
我现在的方法是自己单独做的分页控件,不太美观。
iamxiaozhuang@hotmail.com 欢迎讨论。

#5楼    回复  引用  查看    

2007-02-25 11:39 by 老夫子系

我做了一个测试界面,一个保存按钮,一个SmartGridView,先点复选框选择几行,然后点击保存按钮,将选择行的ID保存到数据库中。可是在保存事件中,怎么获取选择行的ID。为什么点击保存按钮后,会报错!

#6楼 [楼主]   回复  引用  查看    

2007-02-25 13:25 by webabcd

@小庄
找到原因了,RowDataBound事件会被执行两次,索引给隐藏字段赋值的时候就会有问题,想破脑袋也不知道RowDataBound事件为什么会被执行两次。想明白后我再把解决办法贴出来

至于分页样式,我的那个只是改写原来GirdView的分页样式而已,如果用存储过程分页的话,我那个肯定只认为有一页的。
我觉得如果要用存储过程分页的话,肯定是要写一个单独的分页控件的

#7楼 [楼主]   回复  引用  查看    

2007-02-25 13:28 by webabcd

@老夫子系
获取选中行的ID就是查看哪个行的复选框被选中了,然后读出这个行的关键字就ok了

#8楼    回复  引用  查看    

2007-02-27 10:05 by Wyssoft

@webabcd
支持你所做出的努力.
刚放完假,测了一下你的新版本.不过,跟我的想象还有点差别.主要是刷新问题,滚动条是可以保持相对位置了,但想避免刷新.我试用一个UpdatePanel套进去,结果滚动条保持不了位置了.

#9楼 [楼主]   回复  引用  查看    

2007-02-27 11:39 by webabcd

@Wyssoft
那个需要在updatepanel中注册js,做在控件里不方便,有时间了我会贴出一个解决办法的

#10楼    回复  引用  查看    

2007-02-28 14:51 by 孤叶(学习.net框架)

FireFox好像有的功能不支持,你的这个控件.

#11楼 [楼主]   回复  引用  查看    

2007-02-28 16:07 by webabcd

@孤叶(学习.net框架)
确实,我的js水平不够啊,无法为ff写与其适用应的js

#12楼 [楼主]   回复  引用  查看    

2007-03-01 22:21 by webabcd

更新列表1
@小庄 发现的bug描述如下
1,跳到最后一页,全选执行成功,但页面左下角提示脚本错误。
2,然后再转到其它页,全选功能不正常(只选择了最后一页的记录数)。

原因
执行分页或者排序事件之类的,重写的RowDataBound事件会执行两次,第一次DataBound老数据,第二次DataBound新数据;重写的PreRender会执行一次(老数据),而其中调用基类的方法base.OnPreRender(e)会执行两次

为什么会出这样?
不知道

解决办法
数据源的Select事件只会执行一次,并且执行之后会RowDataBound新数据,所以,如果设置一个变量来确保只有数据源的Select事件之后才RowDataBound就ok了
把重写的PreRender换为在GridView的构造函数中增加GridView的事件委托,则没有上述问题

#13楼 [楼主]   回复  引用  查看    

2007-03-01 22:27 by webabcd

更新列表2
@Wyssoft 提出的问题
如果固定行、列的话刷新后,滚动条是可以保持相对位置了,但想避免刷新。我试用一个UpdatePanel套进去,结果滚动条保持不了位置了。

原因
我的代码是用Page来注册客户端代码的,用了asp.net ajax要用ScriptManager来注册客户端代码

解决办法
暴露两个只可访问的公共属性
ScrollX和ScrollY
在页面的代码中如下注册客户端代码即可
ScriptManager.RegisterStartupScript(UpdatePanel1, typeof(UpdatePanel), "js", "document.getElementById('yy_ScrollDiv').scrollLeft=" + SmartGridView1.ScrollX + ";document.getElementById('yy_ScrollDiv').scrollTop=" + SmartGridView1.ScrollY + ";", true);

#14楼    回复  引用  查看    

2007-03-02 09:26 by Wyssoft

@webabcd
不知道是不是跟UpdatePanel有关,在设计模式下老死掉.

ScriptManager.RegisterStartupScript(UpdatePanel1, typeof(UpdatePanel), "js", "document.getElementById('yy_ScrollDiv').scrollLeft=" + SmartGridView1.ScrollX + ";document.getElementById('yy_ScrollDiv').scrollTop=" + SmartGridView1.ScrollY + ";", true);

这段代码应该放在页面中哪个位置比较合适呢?

#15楼 [楼主]   回复  引用  查看    

2007-03-02 10:39 by webabcd

@Wyssoft
如果使用了固定行、列的功能后就会出现这种现象

那段代码可以加到Page_Load里

#16楼    回复  引用  查看    

2007-03-05 09:15 by Wyssoft

@webabcd
为什么会是这样,有没有办法解决呢.我记得以前的版本好像没有吧.
滚动条位置好像可以借助MaintainScrollPositionOnPostback这个属性解决.
你试试,我这没法调了.

#17楼 [楼主]   回复  引用  查看    

2007-03-05 10:13 by webabcd

@Wyssoft
MaintainScrollPositionOnPostback这个属性是相对于浏览器的,我的那个是相对于GridView所在的DIV的,不能借用啊

另外,可能会死掉是因为固定了行、列的原因,因为行、列都有可能固定,所以我在每个单元格都用css调js实现这个功能,比较耗cpu,所以有可能会死掉

还有一种用div冻结行、列的实现方法,但是集成到GridView里超麻烦,所以放弃了

#18楼    回复  引用  查看    

2007-03-09 08:53 by Wyssoft

@webabcd
我决得那个耗cpu问题,真是个很大的问题.应该考虑考虑

#19楼    回复  引用  查看    

2007-03-09 10:13 by Wyssoft

刚发现 用SqlDataSource作数据源,标题不能初固定.是怎么回事.

#20楼 [楼主]   回复  引用  查看    

2007-03-09 12:39 by webabcd

@Wyssoft
确实,冻结行、列后耗cpu问题同时也出现在客户端显示的时候,但以我现在的水平也确实没什么好的解决办法。如果在设计模式中会死掉,那就用在HTML模式下写代码吧。或者先不加冻结行、列的功能,等都设计得差不多了,再在HTML模式下把冻结行、列的功能加上

我没用SqlDataSource数据源做过测试,实际上我从来都没用过SqlDataSource,它会破坏项目中的层次结构,建议兄弟实际开发中也别用它。

#21楼    回复  引用  查看    

2007-03-15 16:07 by wyz

东西确实很好用,但是有一点在开发的时候,预览这个控件的属性时候经常CPU不够用

#22楼 [楼主]   回复  引用  查看    

2007-03-15 20:27 by webabcd

@wyz
这是因为使用了固定行、列功能的原因,因为行、列都有可能固定,所以我在每个单元格都用css调js实现这个功能,比较耗cpu

#23楼    回复  引用  查看    

2007-03-16 13:28 by Wyssoft

@webabcd
在ItemTemplate里加一个DropDownList,结果DropDownList跑到固定行的上面进行移动

#24楼 [楼主]   回复  引用  查看    

2007-03-16 15:13 by webabcd

@Wyssoft
这是IE的BUG,就是当层遇到下拉框时总是挡不了select框

#25楼    回复  引用  查看    

2007-03-19 09:30 by FrankFei

我在针对SmartGridView编程时,
SmartGridView1 = new SmartGridView();
SmartGridView1.RowCommand += new GridViewCommandEventHandler(SmartGridView1_RowCommand);在运行时就是不响应,而如果把SmartGridView中的protected override void OnRowDataBound(GridViewRowEventArgs e)拿掉就可以了,这是为什么呢?

#26楼 [楼主]   回复  引用  查看    

2007-03-19 10:16 by webabcd

@FrankFei
我试了一下,没问题啊

protected void Page_Load(object sender, EventArgs e)
{
SmartGridView1.RowCommand += new GridViewCommandEventHandler(SmartGridView2_RowCommand);
}

protected void SmartGridView2_RowCommand(object sender, GridViewCommandEventArgs e)
{

}

#27楼    回复  引用  查看    

2007-03-19 11:18 by FrankFei

可是我测试下来确实是这样的,下面为源码,能否帮忙看看,谢谢!

public partial class Default3 : System.Web.UI.Page
{
private SmartGridView smartGridView;
protected void Page_Load(object sender, EventArgs e)
{
string connectionString = "Data Source=dev;User ID=user;Password=pw";
OracleDatabase oracleDatabase = new OracleDatabase(connectionString);
OracleCommand oracleCommand = new OracleCommand();
oracleCommand.CommandType = CommandType.Text;
oracleCommand.CommandText = "select * from hr_absence_type";
DataSet dataSet = oracleDatabase.ExecuteDataSet(oracleCommand);

BoundField absenceTypeId = new BoundField();
absenceTypeId.DataField = "absence_type_id";
absenceTypeId.HeaderText = "假别ID";
BoundField absenceCode = new BoundField();
absenceCode.DataField = "absence_code";
absenceCode.HeaderText = "假别代号";
BoundField absenceName = new BoundField();
absenceName.DataField = "absence_name";
absenceName.HeaderText = "假别名称";

TemplateField dataItemIndex = new TemplateField();
GridViewItemTemplate gridViewItemTemplate = new GridViewItemTemplate();
dataItemIndex.ItemTemplate = gridViewItemTemplate;

SmartGridView1 = new SmartGridView();
SmartGridView1.RowCommand += new GridViewCommandEventHandler(SmartGridView1_RowCommand);

SmartGridView1.AutoGenerateColumns = false;
SmartGridView1.Columns.Add(absenceTypeId);
SmartGridView1.Columns.Add(absenceCode);
SmartGridView1.Columns.Add(absenceName);
SmartGridView1.Columns.Add(dataItemIndex);
SmartGridView1.ApplyStyleSheetSkin(this);

SmartGridView1.DataSource = dataSet;
SmartGridView1.DataBind();
Control form = this.FindControl("form1");
form.Controls.Add(SmartGridView1);
}
protected void SmartGridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
this.TextBox1.Text = "第" + (Convert.ToInt32(e.CommandArgument)).ToString() + "行 ";
}
public SmartGridView SmartGridView1
{
get
{
return smartGridView;
}
set
{
smartGridView = value;
}
}

}
class GridViewItemTemplate : ITemplate
{
public GridViewItemTemplate()
{
}

public void InstantiateIn(Control container)
{
Button button = new Button();
button.ID = "btnRightMenuButton";
button.CommandName = "RightMenuButton";
button.DataBinding += new EventHandler(this.OnDataBinding);

container.Controls.Add(button);
}

public void OnDataBinding(object sender, EventArgs e)
{
Button button = (Button)sender;
GridViewRow gridViewRow = (GridViewRow)button.NamingContainer;
button.CommandArgument = gridViewRow.Cells[0].Text.ToString();
}
}

#28楼 [楼主]   回复  引用  查看    

2007-03-19 11:44 by webabcd

@FrankFei
诡异了,我试了一下这个,是可以执行SmartGridView1_RowCommand的

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Data.SqlClient;

using YYControls.SmartGridView;

public partial class Default2 : System.Web.UI.Page
{
private SmartGridView smartGridView;
protected void Page_Load(object sender, EventArgs e)
{
string connectionString = "data source=.;database=Test;User ID=sa;Password=sa";
SqlDataAdapter cmd = new SqlDataAdapter("select * from testtable", connectionString);
DataSet dataSet = new DataSet();
cmd.Fill(dataSet);
cmd.Dispose();

BoundField absenceTypeId = new BoundField();
absenceTypeId.DataField = "name";
absenceTypeId.HeaderText = "name";

TemplateField dataItemIndex = new TemplateField();
GridViewItemTemplate gridViewItemTemplate = new GridViewItemTemplate();
dataItemIndex.ItemTemplate = gridViewItemTemplate;

SmartGridView1 = new SmartGridView();
SmartGridView1.RowCommand += new GridViewCommandEventHandler(SmartGridView1_RowCommand);

SmartGridView1.AutoGenerateColumns = false;
SmartGridView1.Columns.Add(absenceTypeId);
SmartGridView1.Columns.Add(dataItemIndex);
SmartGridView1.ApplyStyleSheetSkin(this);

SmartGridView1.DataSource = dataSet;
SmartGridView1.DataBind();
Control form = this.FindControl("form1");
form.Controls.Add(SmartGridView1);
}
protected void SmartGridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Response.Write("dafds");
}
public SmartGridView SmartGridView1
{
get
{
return smartGridView;
}
set
{
smartGridView = value;
}
}

}

class GridViewItemTemplate : ITemplate
{
public GridViewItemTemplate()
{
}

public void InstantiateIn(Control container)
{
Button button = new Button();
button.ID = "btnRightMenuButton";
button.CommandName = "RightMenuButton";
button.DataBinding += new EventHandler(this.OnDataBinding);

container.Controls.Add(button);
}

public void OnDataBinding(object sender, EventArgs e)
{
Button button = (Button)sender;
GridViewRow gridViewRow = (GridViewRow)button.NamingContainer;
button.CommandArgument = gridViewRow.Cells[0].Text.ToString();
}
}

#29楼    回复  引用  查看    

2007-03-19 14:02 by FrankFei

兄弟,你有点生成后界面上的button,然后有调用如下的内容啊?protected void SmartGridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{

}

太奇怪了!会不会是VS2005的BUG?
但是我把上面的SmartGridView改为GridView,又是好的,奇怪!

#30楼 [楼主]   回复  引用  查看    

2007-03-19 15:28 by webabcd

@FrankFei
经验告诉我,这应该不是VS2005的BUG
我只是把你的程序读数据库的部分改成了sqlserver的,删了几个列

然后按了按钮后会执行这句
protected void SmartGridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Response.Write("dafds");
}

页面显示了dafds

#31楼    回复  引用  查看    

2007-03-19 16:51 by FrankFei

问题找到了,我把你控件中OnRowDataBound的第一行的那个return不小心删除了。只是还不理解真正的原因。
再次感谢你的热心!
向你学习!

#32楼 [楼主]   回复  引用  查看    

2007-03-19 18:10 by webabcd

@FrankFei
我加那句是为了避免下面情况的发生

执行分页或者排序事件之类的,重写的RowDataBound事件会执行两次,第一次DataBound老数据,第二次DataBound新数据;重写的PreRender会执行一次(老数据),而其中调用基类的方法base.OnPreRender(e)会执行两次

实在是不知道为什么会出现这种情况,所以加了那句避免这种情况

大家互相学习,共同提高

【上篇】
【下篇】

抱歉!评论已关闭.