• [原创]ExtAspNet秘密花园(二十) — 表格之模板列与编辑框


    前面我们已经多次见到模板列,只不过那些模板列中放置的都是文本(asp:Label)控件,而本章将会介绍模板列和编辑框(文本输入框、下拉列表、单选框、复选框等)是如何交互的。

    模板列中只能放置Asp.Net控件

    这是ExtAspNet的一个限制,其实在ExtAspNet中只有如下三个地方可以放置Asp.Net控件:

    • 和PageManager控件同级别,也就是form标签的内部;
    • ContentPanel控件内部;
    • 表格中模板列的内部。

    模板列中的文本输入框

    下面通过一个示例讲述如何绑定数据到模板列中的输入框,以及如何在后台代码中获取这些输入框的值,例子的ASPX标签:

       1:  <ext:Grid ID="Grid1" ShowBorder="true" ShowHeader="true" Title="表格" Width="800px"
       2:      runat="server" DataKeyNames="Id,Name">
       3:      <Columns>
       4:          // 省略其他列...
       5:          <ext:TemplateField HeaderText="分组" Width="100px">
       6:              <ItemTemplate>
       7:                  <asp:TextBox ID="tbxGroupName" runat="server" Width="80px" 
       8:                      Text='<%# Eval("Group") %>'></asp:TextBox>
       9:              </ItemTemplate>
      10:          </ext:TemplateField>
      11:      </Columns>
      12:  </ext:Grid>

    这里直接通过Asp.Net控件TextBox的Text属性来绑定数据,非常简单直观。现在的页面效果:

    image

    如何在后台获得这些可能已经被用户修改过的输入框的值呢,来看下示例代码:

       1:  protected void Button1_Click(object sender, EventArgs e)
       2:  {
       3:      StringBuilder sb = new StringBuilder();
       4:      sb.Append("<table style=\"350px;\"><tr><th>编号</th><th>姓名</th><th>用户输入的分组号</th></tr>");
       5:      for (int i = 0, count = Grid1.Rows.Count; i < count; i++)
       6:      {
       7:          sb.Append("<tr>");
       8:          object[] rowDataKeys = Grid1.DataKeys[i];
       9:          sb.AppendFormat("<td>{0}</td>", rowDataKeys[0]);
      10:          sb.AppendFormat("<td>{0}</td>", rowDataKeys[1]);
      11:          
      12:          GridRow row = Grid1.Rows[i];
      13:          System.Web.UI.WebControls.TextBox tbxGroupName = (System.Web.UI.WebControls.TextBox)row.FindControl("tbxGroupName");
      14:          sb.AppendFormat("<td>{0}</td>", tbxGroupName.Text);
      15:   
      16:          sb.Append("<tr>");
      17:      }
      18:   
      19:      sb.Append("</table>");
      20:   
      21:      labResult.Text = sb.ToString();
      22:  }

    其实也很简单,仅需如下步骤:

    1. 为模板列中的输入框控件设置ID,本例中是tbxGroupName;
    2. 后台代码中,先根据行索引获取当前行实例 GridRow row = Grid1.Row[rowIndex];
    3. 调用行的FindControl方法查找其中的Asp.Net控件 (System.Web.UI.WebControls.TextBox)row.FindControl("tbxGroupName");
    4. 这样就能得到输入框控件的Text属性了。

    界面效果图:

    image

    官方示例对本例做了扩展,可以实现如下两个功能:

    1. 使用Tab键遍历所有的文本输入框;
    2. 点击输入框即可选中输入框的全部文本。

    其中第二个功能需要借助JavaScript代码来完成,如果你感兴趣的话,不妨研究一下。

    模板列中的下拉列表

    上例中的数据绑定是直接在ASPX标签中完成的,但是有时不方便在标签中进行数据绑定,甚至控件本身都需要根据数据生成,这就需要通过后台代码完成了。

    我们先来看一个模板列中放置下拉列表的例子:

    image

    来看下ASPX结构的主要部分:

       1:  <ext:Grid ID="Grid1" ShowBorder="true" ShowHeader="true" Title="表格" Width="800px"
       2:          runat="server" DataKeyNames="Id,Name" OnRowDataBound="Grid1_RowDataBound">
       3:      <Columns>
       4:          <ext:TemplateField Width="60px" HeaderText="性别">
       5:              <ItemTemplate>
       6:                  <asp:DropDownList runat="server" ID="ddlGender">
       7:                      <asp:ListItem Text="男" Value="男"></asp:ListItem>
       8:                      <asp:ListItem Text="女" Value="女"></asp:ListItem>
       9:                  </asp:DropDownList>
      10:              </ItemTemplate>
      11:          </ext:TemplateField>
      12:          // 省略其他列...
      13:      </Columns>
      14:  </ext:Grid>

    由于后台数据的性别列是整型值,不方便在ASPX标签中直接绑定,不过我们可以在RowDataBound事件中直接修改渲染后的下拉列表:

       1:  protected void Grid1_RowDataBound(object sender, ExtAspNet.GridRowEventArgs e)
       2:  {
       3:      System.Web.UI.WebControls.DropDownList ddlGender = 
       4:          (System.Web.UI.WebControls.DropDownList)Grid1.Rows[e.RowIndex].FindControl("ddlGender");
       5:   
       6:      DataRowView row = e.DataItem as DataRowView;
       7:   
       8:      int gender = Convert.ToInt32(row["Gender"]);
       9:      if (gender == 1)
      10:      {
      11:          ddlGender.SelectedValue = "男";
      12:      }
      13:      else
      14:      {
      15:          ddlGender.SelectedValue = "女";
      16:      }
      17:  }

    这里的逻辑也很简单,根据行索引和下拉列表ID获取渲染后的下拉列表实例,然后获取相应的数据,并根据此数据更改下拉列表的选中值。

    获取用户可以修改后的下拉列表值和上例类似,就不再赘述。

    image

    后台绑定模板列中的下拉列表

    有时我们可能无法直接在ASPX完成下拉列表,比如需要从数据库读取中国的省份信息并绑定到下拉列表,这就需要在后台完成。

    下列会模拟这一过程,假设性别下拉列表的“男”和“女”是需要读取数据库才能获得的信息,再来看下ASPX标签的定义:

       1:  <ext:Grid ID="Grid1" ShowBorder="true" ShowHeader="true" Title="表格" Width="800px"
       2:          runat="server" DataKeyNames="Id,Name" OnRowDataBound="Grid1_RowDataBound">
       3:      <Columns>
       4:          <ext:TemplateField Width="60px" HeaderText="性别">
       5:              <ItemTemplate>
       6:                  <asp:DropDownList runat="server" ID="ddlGender">
       7:                  </asp:DropDownList>
       8:              </ItemTemplate>
       9:          </ext:TemplateField>
      10:          // 省略其他列...
      11:      </Columns>
      12:  </ext:Grid>

    在后台的行绑定事件中:

       1:  protected void Grid1_RowDataBound(object sender, ExtAspNet.GridRowEventArgs e)
       2:  {
       3:      System.Web.UI.WebControls.DropDownList ddlGender = 
       4:          (System.Web.UI.WebControls.DropDownList)Grid1.Rows[e.RowIndex].FindControl("ddlGender");
       5:   
       6:      List<string> genderList = new List<string>();
       7:      genderList.Add("男");
       8:      genderList.Add("女");
       9:      ddlGender.DataSource = genderList;
      10:      ddlGender.DataBind();
      11:   
      12:      DataRowView row = e.DataItem as DataRowView;
      13:   
      14:      int gender = Convert.ToInt32(row["Gender"]);
      15:      if (gender == 1)
      16:      {
      17:          ddlGender.SelectedValue = "男";
      18:      }
      19:      else
      20:      {
      21:          ddlGender.SelectedValue = "女";
      22:      }
      23:  }

    这里逻辑是:

    1. 首先行渲染完毕,此时模板列的下拉列表为空;
    2. 然后在行绑定事件中,根据行索引和下拉列表ID获取渲染后的下拉列表实例(FindControl);
    3. 查询数据库得到有关下拉列表项的信息,并绑定到此下拉列表实例(DataBind);
    4. 获取相应的数据,并根据此数据更新下拉列表的选中值(SelectedValue )。

    后台更新模板列的值

    后台代码中更新了模板列中的值,有两种情况:

    1. 重新对表格进行了数据绑定(DataBind);
    2. 只更新了部分模板列的值,此时需要手工调用UpdateTemplateFields方法了更新界面显示。

    还是本章开头的第一个例子,我们需要点击更新按钮时将所有的“分组”列的值加一,该怎么实现:

       1:  protected void Button1_Click(object sender, EventArgs e)
       2:  {
       3:      for (int i = 0, count = Grid1.Rows.Count; i < count; i++)
       4:      {
       5:          GridRow row = Grid1.Rows[i];
       6:          System.Web.UI.WebControls.DropDownList ddlGender = 
       7:              (System.Web.UI.WebControls.DropDownList)row.FindControl("ddlGender");
       8:          System.Web.UI.WebControls.TextBox tbxGroupName = 
       9:              (System.Web.UI.WebControls.TextBox)row.FindControl("tbxGroupName");
      10:   
      11:          tbxGroupName.Text = (Convert.ToInt32(tbxGroupName.Text) + 1).ToString();
      12:   
      13:      }
      14:   
      15:      // 如果不是重新绑定数据,则需要手工调用UpdateTemplateFields来更新所有TemplateField中的值
      16:      Grid1.UpdateTemplateFields();
      17:  }

    当然,如果是重新绑定表格的话,就不要调用UpdateTemplateFields方法了。

    小结

    模板列中放置可编辑框在实际项目中也有很大的需求,可以减少打开新窗口编辑的麻烦,同时可以批量编辑。如果你的项目有类似的需求,一定要把这一块吃透。

    下一篇文章我们会介绍如何动态创建表格列,特别是模板列的动态创建需要一定的编程技巧。

    注:《ExtAspNet秘密花园》系列文章由三生石上原创,博客园首发,转载请注明出处。文章目录 官方论坛

  • 相关阅读:
    在DevExpress程序中使用SplashScreenManager控件实现启动闪屏和等待信息窗口
    使用Setup Factory安装包制作工具制作安装包
    PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库
    在DevExpress中使用CameraControl控件进行摄像头图像采集
    读取数据库信息构建视图字段的备注信息,方便程序代码生成
    混合框架中Oracle数据库的还原处理操作
    使用图片视频展示插件blueimp Gallery改造网站的视频图片展示
    .NET缓存框架CacheManager在混合式开发框架中的应用(1)-CacheManager的介绍和使用
    在Winform界面菜单中实现动态增加【最近使用的文件】菜单项
    文字处理控件TX Text Control的使用
  • 原文地址:https://www.cnblogs.com/sanshi/p/2750622.html
Copyright © 2020-2023  润新知