金沙贵宾会官网|金沙贵宾会登录-官网

【A】金沙贵宾会官网超高的返奖率为娱乐者提供资金保障,所以金沙贵宾会登录官网更加的方便了你的娱乐,申请88元彩金,因为在当中不仅仅只有游戏。

表格之动态创建列,左边使用

日期:2019-09-28编辑作者:网络软件

需要处理字符串,按要求长度为5个字符,如果出现位数不够长度,在前面使用"$"符号补足。

有时我们需要根据数据来动态创建表格列,怎么来做到这一点呢?本章会详细讲解。

其实这个问题,实现起来不难,因为C#程序中,就带有此功能,它叫PadLeft()方法。

 

下面Insus.NET在网页中,列举几个例子来说:
图片 1

动态创建的列

还是通过一个示例来看下如何在FineUI中动态创建表格列,示例的界面截图:

图片 2

 

先来看下ASPX的标签定义:

   1:  <ext:Grid ID="Grid1" runat="server" Width="650px" EnableCheckBoxSelect="true" EnableRowNumber="true"

   2:      Title="表格(动态创建的列)">

   3:  </ext:Grid>

 

ASPX标签中没有定义任何列,所有列都是在后台定义的:

   1:  // 注意:动态创建的代码需要放置于Page_Init(不是Page_Load),这样每次构造页面时都会执行

   2:  protected void Page_Init(object sender, EventArgs e)

   3:  {

   4:      InitGrid();

   5:  }

   6:   

   7:  private void InitGrid()

   8:  {

   9:      FineUI.BoundField bf;

  10:   

  11:      bf = new FineUI.BoundField();

  12:      bf.DataField = "Id";

  13:      bf.DataFormatString = "{0}";

  14:      bf.HeaderText = "编号";

  15:      Grid1.Columns.Add(bf);

  16:   

  17:      bf = new FineUI.BoundField();

  18:      bf.DataField = "Name";

  19:      bf.DataFormatString = "{0}";

  20:      bf.HeaderText = "姓名";

  21:      Grid1.Columns.Add(bf);

  22:   

  23:      bf = new FineUI.BoundField();

  24:      bf.DataField = "EntranceYear";

  25:      bf.DataFormatString = "{0}";

  26:      bf.HeaderText = "入学年份";

  27:      Grid1.Columns.Add(bf);

  28:   

  29:      bf = new FineUI.BoundField();

  30:      bf.DataToolTipField = "Major";

  31:      bf.DataField = "Major";

  32:      bf.DataFormatString = "{0}";

  33:      bf.HeaderText = "所学专业";

  34:      bf.ExpandUnusedSpace = true;

  35:      Grid1.Columns.Add(bf);

  36:   

  37:      Grid1.DataKeyNames = new string[] { "Id", "Name" };

  38:  }

  39:   

  40:  protected void Page_Load(object sender, EventArgs e)

  41:  {

  42:      if (!IsPostBack)

  43:      {

  44:          LoadData();

  45:      }

  46:  }

  47:   

  48:  private void LoadData()

  49:  {

  50:      DataTable table = GetDataTable();

  51:   

  52:      Grid1.DataSource = table;

  53:      Grid1.DataBind();

  54:  }

整个代码结构非常清晰,分为页面的初始化阶段和页面的加载阶段。

在页面的初始化阶段:

  1. 创建一个新的FineUI.BoundField实例;
  2. 设置此实例的DataField、DataFormatString、HeaderText等属性;
  3. 将新创建的列添加到Grid1.Columns属性中。

 

页面的加载阶段就是绑定数据到表格,和之前的处理没有任何不同。

 

现在我们要去读取Label+ 奇数的标签值,处理完毕,去显示在Label + 偶数标签上。这涉及到处理奇偶数,例子中共同有8个Label。因此for 8。求奇偶数使用%来实现。

动态创建的模板列

模板列的动态创建有点复杂,我们先来看下创建好的模板列:

图片 3

 

ASPX标签和上面例子一模一样,就不再赘述。我们来看下动态创建模板列的代码:

   1:  FineUI.TemplateField tf = new TemplateField();

   2:  tf.Width = Unit.Pixel(100);

   3:  tf.HeaderText = "性别(模板列)";

   4:  tf.ItemTemplate = new GenderTemplate();

   5:  Grid1.Columns.Add(tf);

 

这里的GenderTemplate是我们自己创建的类,这也是本例的关键点。

   1:  public class GenderTemplate : ITemplate

   2:  {

   3:      public void InstantiateIn(System.Web.UI.Control container)

   4:      {

   5:          AspNet.Label labGender = new AspNet.Label();

   6:          labGender.DataBinding += new EventHandler(labGender_DataBinding);

   7:          container.Controls.Add(labGender);

   8:      }

   9:   

  10:      private void labGender_DataBinding(object sender, EventArgs e)

  11:      {

  12:          AspNet.Label labGender = (AspNet.Label)sender;

  13:   

  14:          IDataItemContainer dataItemContainer = (IDataItemContainer)labGender.NamingContainer;

  15:   

  16:          int gender = Convert.ToInt32(((DataRowView)dataItemContainer.DataItem)["Gender"]);

  17:         

  18:          labGender.Text = (gender == 1) ? "男" : "女";

  19:      }

  20:  }

GenderTemplate实现了ITemplate接口,其中InstantiateIn在需要初始化模板中控件时被调用:

  1. 创建一个Asp.Net的Label控件实例 (AspNet.Label labGender = new AspNet.Label());
  2. 设置数据绑定处理函数(labGender.DataBinding += new EventHandler(labGender_DataBinding));
  3. 将此Label实例添加到模板容器中(container.Controls.Add(labGender))。

 

之后,在对Label进行数据绑定时:

  1. 首先得到当前Label实例,也即是sender对象;
  2. 获取Label的命名容器,此容器实现了IDataItemContainer接口;
  3. 将此接口的DataItem强制转换为DataRowView,因为数据源是DataTable;
  4. 根据数据源的值设置Label的值。

 

上面的两个示例,我们都把动态创建控件的代码当时Page_Init函数中,这是为什么呢?

要想明白其中的道理,我们还是要从Asp.Net中动态添加控件的原理说起。

 

图片 4图片 5图片 6

图片 7

学习Asp.Net的视图状态和生命周期

这个话题比较深入,也不大容易理解,建议大家在阅读本节之前详细了解Asp.Net的视图状态和页面的生命周期,下面是两个非常经典的参考文章(本节的部分图片和文字都来自这两篇文章):

  1. Understanding ASP.NET View State
  2. 创建动态数据输入用户界面

 

执行得到的结果如下,如果位数是答合要求,它直接显示原来的值。
图片 8

Asp.Net页面的生命周期

图片 9

从上图可以看出,Asp.Net页面的生命周期分为如下几个阶段:

  1. 实例化阶段:根据ASPX标签定义的静态结构创建控件的层次结构,并会调用页面的Page_Init事件处理函数。
  2. 加载视图状态阶段(仅回发):将VIEWSTATE中发现的视图状态数据恢复到控件的层次结构中。
  3. 加载回发数据阶段(仅回发):将回发的表单数据恢复到控件的层次结构中,如果表单控件的数据发生变化,还有可能在第5个阶段触发相应的事件。
  4. 加载阶段:此时控件的层次结构已经创建完毕,并且控件的状态已经从视图数据和回发数据中回发,此时可以访问所有的控件属性,并会调用页面的Page_Load事件处理函数。
  5. 触发回发事件(仅回发)阶段:触发回发事件,比如按钮的点击事件、下拉列表的选中项改变事件。
  6. 保存视图状态阶段:保存所有控件的视图状态。
  7. 渲染阶段:将所有页面控件渲染为HTML代码。

上面的这七个阶段是每个Asp.Net开发人员都应该熟悉和掌握的,它可以帮助我们理解页面中Page_Load和事件处理函数的逻辑关系。

 

注意:上述处理过程不管是在页面第一次加载还是在页面回发,都会发生。理解这一点非常重要!

 

动态添加控件的两种模式

动态添加控件需要在加载视图状态和加载回发数据之前进行,因为我们需要能够在添加控件之后恢复这些数据。所以这个阶段就对应了Page_Init处理函数,这也就是为什么上面两个例子都在此函数中动态添加控件。

 

但是由于在初始化阶段时,视图状态和回发数据还没有恢复,因此此时无法访问存储在视图状态或者回发数据中的控件属性。所以还有一个常用的模式是在Page_Init中添加控件,在Page_Load中为动态创建的控件设置默认值。

 

下面两个示例分别展示了动态添加控件的两种模式。

动态添加控件模式一:

   1:  protected void Page_Init(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      lab.Text = "Label1";

   6:   

   7:      Form.Controls.Add(lab);

   8:  }

   9:   

  10:  protected void Page_Load(object sender, EventArgs e)

  11:  {

  12:      

  13:  }

 

动态添加控件模式二:

   1:  protected void Page_Init(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:   

   6:      Form.Controls.Add(lab);

   7:  }

   8:   

   9:  protected void Page_Load(object sender, EventArgs e)

  10:  {

  11:      if (!IsPostBack)

  12:      {

  13:          AspNet.Label lab = Form.FindControl("Label1") as AspNet.Label;

  14:          lab.Text = "Label1";

  15:      }

  16:  }

第二种模式是在初始化阶段添加动态控件,然后在加载阶段(!IsPostBack)设置控件的默认值。

 

 

 

 

错误使用动态添加控件的例子一

你可能会想上例中,为什么要将设置控件默认值的代码放在 !IsPostBack 逻辑块中,下面就来看下不放在!IsPostBack 逻辑块中的例子。

首先看下ASPX标签结构:

   1:  <form id="form1" runat="server">

   2:  <asp:Button ID="Button1" Text="Change Text" OnClick="Button1_Click" runat="server" />

   3:  <asp:Button ID="Button2" Text="Empty Post" runat="server" />

   4:  <br />

   5:  </form>

再看下后台的初始化代码:

   1:  protected void Page_Init(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:   

   6:      Form.Controls.Add(lab);

   7:  }

   8:   

   9:  protected void Page_Load(object sender, EventArgs e)

  10:  {

  11:      AspNet.Label lab = Form.FindControl("Label1") as AspNet.Label;

  12:      lab.Text = "Label1";

  13:  }

  14:   

  15:   

  16:  protected void Button1_Click(object sender, EventArgs e)

  17:  {

  18:      AspNet.Label lab = Form.FindControl("Label1") as AspNet.Label;

  19:      lab.Text = "Changed Label1";

  20:  }

按如下步骤操作:

  1. 第一次打开页面,显示的文本是 Label1;
  2. 点击“Change Text”按钮,显示的文本是 Changed Label1;
  3. 点击“Empty Post”按钮,显示的文本是 Label1。

这就不对了,点击“Empty Post”按钮时显示的文本也应该是 Changed Label1,但是上例中文本控件的视图状态没有保持,这是为什么呢?

原因也很简单,当用户进行第三步操作(即点击“Empty Post”按钮):

  1. 在初始化阶段(Page_Init),添加了动态控件Label1;
  2. 根据页面的生命周期,之后进行的是加载视图状态(LoadViewState),此时动态控件Label1的文本是 Changed Label1;
  3. 加载视图状态之后就开始跟踪视图状态的变化;
  4. 在加载阶段(Page_Load),跟踪到了控件属性值的变化,Label1的值就又从Chenged Label1变成了Label1。

 

关键点:当控件完成加载视图状态阶段后,就会立即开始跟踪其视图状态的改变,之后任何对其属性的改变都会影响最终的控件视图状态。

理解这一点非常重要,如果你尚未理解这句话的意思,请多读几遍,再多读几遍,这句话同时会影响后面介绍的另外两种动态添加控件的模式。

 

如果你能理解上面提到的过程,说明你已经掌握了Asp.Net的页面生命周期和ViewState的加载过程了。

 

动态添加控件的另外两种模式

除了在初始化阶段动态添加控件外,还可以再加载阶段添加控件。这是因为当把一个控件添加到另一个控件的Controls集合时,所添加的控件的生命周期会立即同步到父控件的生命周期。比如,如果父控件处于初始化阶段,则会触发所添加控件的初始化事件;如果父控件处于加载阶段,则会触发所添加控件的的初始化事件、加载视图事件、加载回发数据事件以及加载事件。

 

由此,我们就有了另外两种动态添加控件的模式:

动态添加控件模式三:

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      lab.Text = "Label1";

   6:      Form.Controls.Add(lab);

   7:  }

 

对于这一种模式,你是否有这样的疑问?:

如果此标签的Text属性在某次Ajax回发时改变了,那么下次Ajax回发时,创建此标签并赋默认值会不会覆盖恢复的视图状态呢(因为此时已经过了加载视图状态阶段)?

其实不会这样的,虽然在Page_Load已经过了加载视图状态阶段,但是由于此标签控件尚未添加到控件层次结构中,所以尚未经历加载视图状态阶段,只有在Controls.Add之后才会经历标签控件的初始化阶段、加载视图状态阶段、加载回发数据阶段和加载阶段。

 

下面通过一个例子说明,首先看下ASPX标签结构:

   1:  <form id="form1" runat="server">

   2:  <asp:Button ID="Button1" Text="Change Text" OnClick="Button1_Click" runat="server" />

   3:  <asp:Button ID="Button2" Text="Empty Post" runat="server" />

   4:  <br />

   5:  </form>

后台代码:

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      lab.Text = "Label1";

   6:      Form.Controls.AddAt(label2Index, lab);

   7:  }

   8:   

   9:  protected void Button1_Click(object sender, EventArgs e)

  10:  {

  11:      AspNet.Label lab = Form.FindControl("Label1") as AspNet.Label;

  12:      lab.Text = "Changed Label1";

  13:  }

进行如下操作:

  1. 第一次打开页面,显示的文本是 Label1;
  2. 点击“Change Text”按钮,显示的文本是 Changed Label1;
  3. 在Page_Load中设置断点,点击“Empty Post”按钮,观察标签的Text属性如下所示。

 

在执行Controls.Add之前,文本值还是Label1:

图片 10

 

在执行Controls.Add之后,文本值从视图状态恢复,变成了 Changed Label1:

图片 11

 

 

动态添加控件模式四:

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      

   6:      Form.Controls.Add(lab);

   7:   

   8:      if (!IsPostBack)

   9:      {

  10:          lab.Text = "Label1";

  11:      }

  12:  }

 

错误使用动态添加控件的例子二

如果你认为自己已经掌握了动态添加控件的原理,不妨来看下面这个错误的例子,看能否指出其中错误的关键。

先来看下ASPX标签结构:

   1:  <form id="form1" runat="server">

   2:  <asp:Button ID="Button2" Text="Empty Post" runat="server" />

   3:  <br />

   4:  </form>

 

在看后台初始化代码:

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      if (!IsPostBack)

   6:      {

   7:          lab.Text = "Label1";

   8:      }

   9:   

  10:      Form.Controls.Add(lab);

  11:  }

是不是和动态添加控件模式四比较类似,不过这里的用法却是错误的,你能看出问题所在吗?

 

来运行一把:

  1. 第一次加载页面,显示的文本是Label1;
  2. 点击“Empty Post”按钮,显示的文本为空(这就不对了,应该还是Label1)。

 

为什么会出现这种情况?我们来分析一下:

  • 第一次加载页面时,设置了文本标签的默认值,然后添加到控件层次结构中;
  • 添加到控件层次结构后,即开始跟踪视图状态的变化,但是此标签的Text属性并没改变,所以最终没有保存到视图状态中;
  • 点击按钮回发时,文本标签的默认值为空,然后添加到控件层次结构中,在加载视图状态阶段没有发现文本标签的视图,所以最终显示为空。

 

那为什么模式四是正确的呢?

简单来说,修改标签的Text属性时已经在跟踪视图状态的改变了,所以这个修改的值被保存了下来;下次回发时又将此值从视图中恢复了出来。

 

 

错误使用动态添加控件的例子三

如果上面的都掌握了,再来看下面这个错误的示例,ASPX标签结构如下:

   1:  <form id="form1" runat="server">

   2:  <asp:Button ID="Button2" Text="Empty Post" runat="server" />

   3:  <br />

   4:  <asp:Label ID="Label2" Text="Label2" runat="server"></asp:Label>

   5:  </form>

后台初始化代码如下:

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:      AspNet.Label lab = new AspNet.Label();

   4:      lab.ID = "Label1";

   5:      lab.Text = "Label1";

   6:      

   7:      int label2Index = Form.Controls.IndexOf(Label2);

   8:   

   9:      Form.Controls.AddAt(label2Index, lab);

  10:   

  11:   

  12:      if (!IsPostBack)

  13:      {

  14:          lab.Text = "Changed Label1";

  15:      }

  16:  }

这段代码进行了如下处理:

  1. 新创建一个标签实例Label1,并设置默认值Label1;
  2. 找到页面上现有标签Label2在父控件中的索引号;
  3. 将新创建的Label1控件插入Label2所在的位置,也即是将Label2向后移动一个位置;
  4. 在页面第一次加载时更改新创建标签Label1的文本为Changed Label1。

 

我们来看下页面第一个加载的显示:

图片 12

一切正常,被改变文本值的Label1位于Label2的前面。

 

然后点击“Empty Post”按钮,会出现如下情况:

图片 13

为什么本应该保持状态的Label2,现在的值却变成了Changed Label1?

 

根本原因是Asp.Net保存保存视图状态的方式,是按照控件出现的顺序保存的,当然恢复也是按照顺序进行的,关于这一特性,我有专门一篇文章详细阐述。

 

总之,简单两句话:

  1. 在Page_Load中动态添加控件时,不要改变现有控件的顺序;
  2. 如果想改变现有控件的顺序,可以再Page_Init中进行添加。

 

 

或者简单一句话:在ASP.NET中,所有动态添加控件的代码都要放到 Page_Init 中进行!

 

 

小结

其实在FineUI中编写动态创建的表格列非常简单,但是要想理解其中原理,就不那么简单了。本篇文章的最后一节详细描述了动态创建控件的原理,也希望大家能够细细品味,深入了解Asp.Net的内部运行机制。

下一篇文章我们会详细讲解如何从表格导出Excel文件。

 

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

本文由金沙贵宾会官网发布于网络软件,转载请注明出处:表格之动态创建列,左边使用

关键词:

The Coroutine

关于Coroutine 金沙贵宾会官网,说到coroutine就不的不说subroutine,也就是我们常用到的一般函数。调用一个函数开始执行...

详细>>

我行你也行

head head meta http-equiv="Content-Type" content="text/html; charset=UTF-8" / title大图轮播/title style type="text/css" * { margin: 0px; padding: 0...

详细>>

TextBox中只能输入数字的几种常用方法

private void txtGoodsGroup_KeyPress(object sender, KeyPressEventArgse) { base.OnKeyPress; if e.KeyChar = 65296 e.KeyChar = 65305) { e.KeyChar = e.KeyCh...

详细>>

2008配置使用动态IP和备用地址,配置内网DNS实现

用DNS地址限制网站访问 在设置DNS地址之前我们需要知道DNS地址是什么? DNS地址是一个域名服务器地址,它可以把用户...

详细>>