[原创]ExtAspNet秘密花园(十七) — 表格之扩展列
ExtAspNet为表格控件提供非常丰富的扩展列,这些扩展列不仅丰富了数据展示的形式,而且极大地减少了程序员的编码量。
序号列与复选列
首先来看下序号列和复选列的实际效果:
序号列和复选列只能出现在表格最前面的两个位置,并且启用这两个列的方法也非常简单:
只需要设置表格的EnableRowNumber和EnableCheckBoxSelect属性为true即可!
注意:序号列表示的是当前页的顺序,因此即使表格翻页后依然是从1开始的。
单选模式与多选模式
表格默认是多选模式,也就是可以一次选择多条数据,选择多条数据的方式和Windows下选择文件的方式类似:
- 多次点击复选列的复选框来选择多行数据;
- 按下Shift键选择连续的多行数据;
- 按下Control键选择不连续的多行数据。
注意:点击另一行会取消之前的所有选中行数据!
如果想启用表格的单选模式,只需要设置EnableMultiSelect属性为false即可!
如何在后台获得选中的行?
1: protected void Button1_Click(object sender, EventArgs e)
2: {
3: StringBuilder sb = new StringBuilder();
4: int[] selections = Grid1.SelectedRowIndexArray;
5: foreach (int rowIndex in selections)
6: {
7: sb.AppendFormat("行索引:{0} 用户名:{1}<br />", rowIndex, Grid1.DataKeys[rowIndex][1]);
8: }
9: labResult.Text = sb.ToString();
10: }
通过如下步骤获得选中行的数据:
- 通过表格的SelectedRowIndexArray获得选中行的索引号列表;
- 通过表格的DataKeys(二维数组)获取本行的数据列表,这就需要事先设置表格的DataKeyNames属性(本例中是"Id,Name")。
行扩展列
先来看下行扩展列的显示效果:
看似复杂,其实实现起来相当的简单,行扩展列其实就是一个带RenderAsRowExpander属性的模板列:
1: <ext:Grid ID="Grid1" ShowBorder="true" ShowHeader="true" Title="表格" Width="800px"
2: runat="server" DataKeyNames="Id,Name">
3: <Columns>
4: <ext:TemplateField RenderAsRowExpander="true">
5: <ItemTemplate>
6: <div class="expander">
7: <p>
8: <strong>姓名:</strong><%# Eval("Name") %></p>
9: <p>
10: <strong>简介:</strong><%# Eval("Desc") %></p>
11: </div>
12: </ItemTemplate>
13: </ext:TemplateField>
14: <ext:TemplateField Width="60px">
15: <ItemTemplate>
16: <asp:Label ID="Label1" runat="server" Text='<%# Container.DataItemIndex + 1 %>'></asp:Label>
17: </ItemTemplate>
18: </ext:TemplateField>
19: <ext:BoundField Width="100px" DataField="Name" DataFormatString="{0}" HeaderText="姓名" />
20: // 省略其他列...
21: </Columns>
22: </ext:Grid>
行扩展列默认是折叠起来的,如何让所有的行扩展列默认打开呢?
ExtAspNet考虑到了这个实际的需求,只需要设置一个属性ExpandAllRowExpanders即可实现如下效果:
模拟树列
模拟树列是ExtAspNet的一个简单创新,却非常有用,来看实际效果:
大家也可以先考虑下如何实现这个效果,为了尽量和普通表格的数据绑定保持一致,数据源也必须是DataTable或者IEnumerable。
有了这个设定,问题就简单了,我们只需要为每行数据准备一个表示树层次的字段即可。
就本例而言,如果“中国”行的树层次为0,则有如下简单的规则:
- 中国:0
- 河南省:1
- 驻马店市:2
- 漯河市:2
- 安徽省:1
- 合肥市:2
- 黄山市:2
下面来看下模拟此结构的数据实现代码:
1: private static DataTable IniGrid()
2: {
3: DataTable table = new DataTable();
4: DataColumn column1 = new DataColumn("Id", typeof(int));
5: DataColumn column2 = new DataColumn("Name", typeof(String));
6: DataColumn column3 = new DataColumn("Group", typeof(String));
7: DataColumn column4 = new DataColumn("TreeLevel", typeof(int));
8: table.Columns.Add(column1);
9: table.Columns.Add(column2);
10: table.Columns.Add(column3);
11: table.Columns.Add(column4);
12:
13: DataRow row = table.NewRow();
14: row[0] = 101;
15: row[1] = "中国";
16: row[2] = "1";
17: row[3] = 0;
18: table.Rows.Add(row);
19:
20: row = table.NewRow();
21: row[0] = 102;
22: row[1] = "河南省";
23: row[2] = "2";
24: row[3] = 1;
25: table.Rows.Add(row);
26:
27: row = table.NewRow();
28: row[0] = 103;
29: row[1] = "驻马店市";
30: row[2] = "3";
31: row[3] = 2;
32: table.Rows.Add(row);
33:
34: row = table.NewRow();
35: row[0] = 104;
36: row[1] = "漯河市";
37: row[2] = "3";
38: row[3] = 2;
39: table.Rows.Add(row);
40:
41: row = table.NewRow();
42: row[0] = 105;
43: row[1] = "安徽省";
44: row[2] = "2";
45: row[3] = 1;
46: table.Rows.Add(row);
47:
48: row = table.NewRow();
49: row[0] = 106;
50: row[1] = "合肥市";
51: row[2] = "3";
52: row[3] = 2;
53: table.Rows.Add(row);
54:
55: row = table.NewRow();
56: row[0] = 107;
57: row[1] = "黄山市";
58: row[2] = "3";
59: row[3] = 2;
60: table.Rows.Add(row);
61:
62: return table;
63: }
来看下ASPX标签结构,我们需要为“地区”列指定要绑定的树层次字段:
1: <ext:Grid ID="Grid1" Title="表格" ShowBorder="true" ShowHeader="true" AutoHeight="true"
2: runat="server" EnableCheckBoxSelect="True" DataKeyNames="Id,Name" Width="800px"
3: EnableRowNumber="True">
4: <Columns>
5: <ext:BoundField DataField="Name" DataSimulateTreeLevelField="TreeLevel" DataFormatString="{0}"
6: HeaderText="地区" ExpandUnusedSpace="True" />
7: <ext:ImageField Width="60px" DataImageUrlField="Group" DataImageUrlFormatString="~/images/16/{0}.png"
8: HeaderText="分组"></ext:ImageField>
9: </Columns>
10: </ext:Grid>
注意:“地区”列的DataSimulateTreeLevelField属性将此列转换为模拟树的列。
弹出窗体列
弹出窗口列,顾名思义就是点击可以弹出窗体的列,其实用模板列也完全可以实现,只不过弹出窗体列可以简化我们的代码编写。
首先看下显示效果:
要实现此效果,页面上必须事先定义一个隐藏的Window控件,如下所示:
1: <ext:Window ID="Window1" Title="编辑" Popup="false" EnableIFrame="true" runat="server"
2: CloseAction="HidePostBack" EnableConfirmOnClose="true" IFrameUrl="about:blank"
3: EnableMaximize="true" EnableResize="true" OnClose="Window1_Close" Target="Top"
4: IsModal="True" Width="750px" Height="450px">
5: </ext:Window>
关于Window控件,后面会有专门篇幅讲解,这就不多说。
而弹出窗体列的作用就是生成一个可以点击的锚点链接,当用户点击时在客户端直接弹出这个窗体。
模板列实现弹出窗体列的功能
首先来看下使用模板列的ASPX标签定义:
1: <ext:TemplateField HeaderText="模板列" Width="60px">
2: <ItemTemplate>
3: <a href="javascript:<%# GetEditUrl(Eval("Id"), Eval("Name")) %>">编辑</a>
4: </ItemTemplate>
5: </ext:TemplateField>
再来看下GetEditUrl函数的定义:
1: protected string GetEditUrl(object id, object name)
2: {
3: return Window1.GetShowReference("grid_iframe_window.aspx?id=" + id, "编辑 - " + name);
4: }
弹出窗体列的结构
而相同的功能使用弹出窗体列,只需要ASPX标签定义就行了,而且可以方便地定义弹出窗体标题,IFrame地址等属性:
1: <ext:WindowField ColumnID="myWindowField" Width="60px" WindowID="Window1" HeaderText="窗口列"
2: Icon="Pencil" ToolTip="编辑" DataTextFormatString="{0}" DataIFrameUrlFields="Id"
3: DataIFrameUrlFormatString="grid_iframe_window.aspx?id={0}" DataWindowTitleField="Name"
4: DataWindowTitleFormatString="编辑 - {0}" />
小结
ExtAspNet对表格的扩展列不仅丰富了数据展现的形式,而且极大的方便了代码的编写。特别是序号列、复选列以及弹出窗体列在实际项目中非常实用,需要大家熟练掌握。下一篇文章,我们会详细讨论表格中的各种事件,其实我们在上一篇文章已经接触到了排序和翻页两种事件,除此之外还有更多的事件等待着我们去探索学习。