ASP.NET数据绑定控件开发浅析

本篇将开始介绍如自定义ASP.NET数据绑定控件,这里感谢很多人的支持,有你们的支持很高兴.

成都创新互联公司凭借专业的设计团队扎实的技术支持、优质高效的服务意识和丰厚的资源优势,提供专业的网站策划、成都做网站、成都网站建设、网站优化、软件开发、网站改版等服务,在成都十载的网站建设设计经验,为成都成百上千中小型企业策划设计了网站。

这里首先需要大家熟悉ASP.NET模板控件的使用,还有自定义模板控件.因为数据绑定控件多是基于模板控件的.

ASP.NET数据绑定控件一.回顾

如果你使用过ASP.NET内置的数据控件(如DataList,Repeater),你一定会这么做

1.设置数据源 DataSource属性

2.调用数据绑定  DataBind方法

3.在控件的不同模板内使用绑定语法显示数据

这三步应该是必须要做的

其他更多的

你可能需要对绑定的数据进行统一的一些操作(如时间格式化),或者对数据的某一项进行操作(对某一项进行格式化),或者需要触发模板控件内的一些事件(如databound事件).

根据上面的一些需求,我们需要这样做

1.对绑定的数据进行统一的一些操作: 为数据绑定控件定义Item项(表示列表的一条数据, 如Repeater的RepeaterItem)

2.对数据的某一项进行操作: 因为定义了Item项,那你肯定需要一个ItemCollection集合,其可以方便的为你检索数据

3.因为定义了RepeaterItem,原先的EventArgs和CommandEventArgs已经无法满足需求,我们需要自定义委托及其一个为控件提供数据的的ItemEventArgs

上面三点有些并非必须定义,如第2点,还需要根据具体需求来定.但一个完成的控件是需要的.

ASP.NET数据绑定控件二.为数据控件做好准备

这次的demo为不完整的Datalist控件,来源还是MSDN的例子,我们命名为TemplatedList,此控件未定义ItemCollection集合

好了,根据上面的分析我们先为TemplatedList提供项和委托及为事件提供数据的几个EventArgs,请看下面类图

1.TemplatedListCommandEventArgs为Command事件提供数据

2.TemplatedListItemEventArgs为一般项提供数据

3.TemplatedListItem表示TemplatedList的项

ASP.NET数据绑定控件三.编写TemplatedList

1.TemplatedList主要功能简介

提供一个ItemTemplate模板属性,提供三种不同项样式,ItemCommand 事件冒泡事件及4个事件

2.实现主要步骤

以下为必须

(1)控件必须实现 System.Web.UI.INamingContainer 接口

(2)定义至少一个模板属性

(3)定义DataSource数据源属性

(4)定义控件项DataItem,即模板的一个容器

(5)重写DataBind 方法及复合控件相关方法(模板控件为特殊的复合控件)

当然还有其他额外的属性,样式,事件

3.具体实现

下面我们来具体看实现方法

(1)定义控件成员属性

 
 
 
 
  1. #region 静态变量
  2.         private static readonly object EventSelectedIndexChanged = new object();
  3.         private static readonly object EventItemCreated = new object();
  4.         private static readonly object EventItemDataBound = new object();
  5.         private static readonly object EventItemCommand = new object();
  6.         #endregion
  7.         成员变量#region 成员变量
  8.         private IEnumerable dataSource;
  9.         private TableItemStyle itemStyle;
  10.         private TableItemStyle alternatingItemStyle;
  11.         private TableItemStyle selectedItemStyle;
  12.         private ITemplate itemTemplate;
  13.         #endregion
  14.         控件属性#region 控件属性
  15.         [
  16.         Category("Style"),
  17.         Description("交替项样式"),
  18.         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  19.         NotifyParentProperty(true),
  20.         PersistenceMode(PersistenceMode.InnerProperty),
  21.         ]
  22.         public virtual TableItemStyle AlternatingItemStyle
  23.         {
  24.             get
  25.             {
  26.                 if (alternatingItemStyle == null)
  27.                 {
  28.                     alternatingItemStyle = new TableItemStyle();
  29.                     if (IsTrackingViewState)
  30.                         ((IStateManager)alternatingItemStyle).TrackViewState();
  31.                 }
  32.                 return alternatingItemStyle;
  33.             }
  34.         }
  35.         [
  36.         Category("Style"),
  37.         Description("一般项样式"),
  38.         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  39.         NotifyParentProperty(true),
  40.         PersistenceMode(PersistenceMode.InnerProperty),
  41.         ]
  42.         public virtual TableItemStyle ItemStyle
  43.         {
  44.             get
  45.             {
  46.                 if (itemStyle == null)
  47.                 {
  48.                     itemStyle = new TableItemStyle();
  49.                     if (IsTrackingViewState)
  50.                         ((IStateManager)itemStyle).TrackViewState();
  51.                 }
  52.                 return itemStyle;
  53.             }
  54.         }
  55.         [
  56.          Category("Style"),
  57.          Description("选中项样式"),
  58.          DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  59.          NotifyParentProperty(true),
  60.          PersistenceMode(PersistenceMode.InnerProperty),
  61.          ]
  62.         public virtual TableItemStyle SelectedItemStyle
  63.         {
  64.             get
  65.             {
  66.                 if (selectedItemStyle == null)
  67.                 {
  68.                     selectedItemStyle = new TableItemStyle();
  69.                     if (IsTrackingViewState)
  70.                         ((IStateManager)selectedItemStyle).TrackViewState();
  71.                 }
  72.                 return selectedItemStyle;
  73.             }
  74.         }
  75.         [
  76.         Bindable(true),
  77.         Category("Appearance"),
  78.         DefaultValue(-1),
  79.         Description("The cell padding of the rendered table.")
  80.         ]
  81.         public virtual int CellPadding
  82.         {
  83.             get
  84.             {
  85.                 if (ControlStyleCreated == false)
  86.                 {
  87.                     return -1;
  88.                 }
  89.                 return ((TableStyle)ControlStyle).CellPadding;
  90.             }
  91.             set
  92.             {
  93.                 ((TableStyle)ControlStyle).CellPadding = value;
  94.             }
  95.         }
  96.         [
  97.         Bindable(true),
  98.         Category("Appearance"),
  99.         DefaultValue(0),
  100.         Description("The cell spacing of the rendered table.")
  101.         ]
  102.         public virtual int CellSpacing
  103.         {
  104.             get
  105.             {
  106.                 if (ControlStyleCreated == false)
  107.                 {
  108.                     return 0;
  109.                 }
  110.                 return ((TableStyle)ControlStyle).CellSpacing;
  111.             }
  112.             set
  113.             {
  114.                 ((TableStyle)ControlStyle).CellSpacing = value;
  115.             }
  116.         }
  117.         [
  118.         Bindable(true),
  119.         Category("Appearance"),
  120.         DefaultValue(GridLines.None),
  121.         Description("The grid lines to be shown in the rendered table.")
  122.         ]
  123.         public virtual GridLines GridLines
  124.         {
  125.             get
  126.             {
  127.                 if (ControlStyleCreated == false)
  128.                 {
  129.                     return GridLines.None;
  130.                 }
  131.                 return ((TableStyle)ControlStyle).GridLines;
  132.             }
  133.             set
  134.             {
  135.                 ((TableStyle)ControlStyle).GridLines = value;
  136.             }
  137.         }
  138.         [
  139.         Bindable(true),
  140.         Category("Data"),
  141.         DefaultValue(null),
  142.         Description("数据源"),
  143.         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
  144.         ]
  145.         public IEnumerable DataSource
  146.         {
  147.             get
  148.             {
  149.                 return dataSource;
  150.             }
  151.             set
  152.             {
  153.                 dataSource = value;
  154.             }
  155.         }
  156.         [
  157.         Browsable(false),
  158.         DefaultValue(null),
  159.         Description("项模板"),
  160.         PersistenceMode(PersistenceMode.InnerProperty),
  161.         TemplateContainer(typeof(TemplatedListItem))
  162.         ]
  163.         public virtual ITemplate ItemTemplate
  164.         {
  165.             get
  166.             {
  167.                 return itemTemplate;
  168.             }
  169.             set
  170.             {
  171.                 itemTemplate = value;
  172.             }
  173.         }
  174.         [
  175.         Bindable(true),
  176.         DefaultValue(-1),
  177.         Description("选中项索引,默认为-1")
  178.         ]
  179.         public virtual int SelectedIndex
  180.         {
  181.             get
  182.             {
  183.                 object o = ViewState["SelectedIndex"];
  184.                 if (o != null)
  185.                     return (int)o;
  186.                 return -1;
  187.             }
  188.             set
  189.             {
  190.                 if (value < -1)
  191.                 {
  192.                     throw new ArgumentOutOfRangeException();
  193.                 }
  194.                 //获取上次选中项
  195.                 int oldSelectedIndex = SelectedIndex;
  196.                 ViewState["SelectedIndex"] = value;
  197.                 if (HasControls())
  198.                 {
  199.                     Table table = (Table)Controls[0];
  200.                     TemplatedListItem item;
  201.                     //第一次选中项不执行
  202.                     if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
  203.                     {
  204.                         item = (TemplatedListItem)table.Rows[oldSelectedIndex];
  205.                         //判断项类型,为了将选中项还原为数据项
  206.                         if (item.ItemType != ListItemType.EditItem)
  207.                         {
  208.                             ListItemType itemType = ListItemType.Item;
  209.                             if (oldSelectedIndex % 2 != 0)
  210.                                 itemType = ListItemType.AlternatingItem;
  211.                             item.SetItemType(itemType);
  212.                         }
  213.                     }
  214.                     //第一次执行此项,并一直执行
  215.                     if ((value != -1) && (table.Rows.Count > value))
  216.                     {
  217.                         item = (TemplatedListItem)table.Rows[value];
  218.                         item.SetItemType(ListItemType.SelectedItem);
  219.                     }
  220.                 }
  221.             }
  222.         }
  223.  
  224.         #endregion

成员如下(可以看上面类图)

1.三个项样式和三个样式属性

2.公开DataSource数据源属性,一个模板属性

3.SelectedIndex索引属性

前面的相信大家都很容易明白,其中的三个项样式我们需要为其重写视图状态管理,不熟悉可以看以前的随笔,这里不再重复.

SelectedIndex属性比较复杂,这里重点介绍此属性

SelectedIndex索引属性默认为-1,

我给出了注释,在赋值前先记录下了上次的选中项,为恢复样式而做准备

 
 
 
 
  1. //获取上次选中项
  2.  int oldSelectedIndex = SelectedIndex;
  3.  ViewState["SelectedIndex"] = value;

当第一次更改SelectedIndex属性时只执行下列代码(将此项标记为选中项),因为初始化时的没有oldSelectedIndex,不需要恢复样式

 
 
 
 
  1. //第一次执行此项,并一直执行
  2.                     if ((value != -1) && (table.Rows.Count > value))
  3.                     {
  4.                         item = (TemplatedListItem)table.Rows[value];
  5.                         item.SetItemType(ListItemType.SelectedItem);
  6.                     }

再次执行时,恢复oldSelectedIndex选中项样式

 
 
 
 
  1. //第一次选中项不执行
  2. if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
  3. {
  4.     item = (TemplatedListItem)table.Rows[oldSelectedIndex];
  5.     //判断项类型,为了将选中项还原为数据项
  6.     if (item.ItemType != ListItemType.EditItem)
  7.     {
  8.         ListItemType itemType = ListItemType.Item;
  9.         if (oldSelectedIndex % 2 != 0)
  10.             itemType = ListItemType.AlternatingItem;
  11.         item.SetItemType(itemType);
  12.     }
  13. }

相信这样的解释你会明白

(2)定义控件成员事件

我们可以用上刚才我们声明的委托了,即然你定义了这么多事件,就该为其安排触发的先后.所以这个要特别注意,等下会再次提到.

 
 
 
 
  1. #region 事件
  2.         protected virtual void OnItemCommand(TemplatedListCommandEventArgs e)
  3.         {
  4.             TemplatedListCommandEventHandler onItemCommandHandler = (TemplatedListCommandEventHandler)Events[EventItemCommand];
  5.             if (onItemCommandHandler != null) onItemCommandHandler(this, e);
  6.         }
  7.         protected virtual void OnItemCreated(TemplatedListItemEventArgs e)
  8.         {
  9.             TemplatedListItemEventHandler onItemCreatedHandler = (TemplatedListItemEventHandler)Events[EventItemCreated];
  10.             if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
  11.         }
  12.         protected virtual void OnItemDataBound(TemplatedListItemEventArgs e)
  13.         {
  14.             TemplatedListItemEventHandler onItemDataBoundHandler = (TemplatedListItemEventHandler)Events[EventItemDataBound];
  15.             if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
  16.         }
  17.         protected virtual void OnSelectedIndexChanged(EventArgs e)
  18.         {
  19.             EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
  20.             if (handler != null) handler(this, e);
  21.         }
  22.         [
  23.         Category("Action"),
  24.         Description("Raised when a CommandEvent occurs within an item.")
  25.         ]
  26.         public event TemplatedListCommandEventHandler ItemCommand
  27.         {
  28.             add
  29.             {
  30.                 Events.AddHandler(EventItemCommand, value);
  31.             }
  32.             remove
  33.             {
  34.                 Events.RemoveHandler(EventItemCommand, value);
  35.             }
  36.         }
  37.         [
  38.         Category("Behavior"),
  39.         Description("Raised when an item is created and is ready for customization.")
  40.         ]
  41.         public event TemplatedListItemEventHandler ItemCreated
  42.         {
  43.             add
  44.             {
  45.                 Events.AddHandler(EventItemCreated, value);
  46.             }
  47.             remove
  48.             {
  49.                 Events.RemoveHandler(EventItemCreated, value);
  50.             }
  51.         }
  52.         [
  53.         Category("Behavior"),
  54.         Description("Raised when an item is data-bound.")
  55.         ]
  56.         public event TemplatedListItemEventHandler ItemDataBound
  57.         {
  58.             add
  59.             {
  60.                 Events.AddHandler(EventItemDataBound, value);
  61.             }
  62.             remove
  63.             {
  64.                 Events.RemoveHandler(EventItemDataBound, value);
  65.             }
  66.         }
  67.         [
  68.         Category("Action"),
  69.         Description("Raised when the SelectedIndex property has changed.")
  70.         ]
  71.         public event EventHandler SelectedIndexChanged
  72.         {
  73.             add
  74.             {
  75.                 Events.AddHandler(EventSelectedIndexChanged, value);
  76.             }
  77.             remove
  78.             {
  79.                 Events.RemoveHandler(EventSelectedIndexChanged, value);
  80.             }
  81.         }
  82.         #endregion

(3)关键实现

我们为控件提供了这么多东西,剩下的事情就是要真正去实现功能了

1.重写DataBind方法

当控件绑定数据时首先会执行此方法触发DataBinding事件

 
 
 
 
  1. //控件执行绑定时执行
  2. public override void DataBind()
  3. {
  4.     base.OnDataBinding(EventArgs.Empty);
  5.     //移除控件
  6.     Controls.Clear();
  7.     //清除视图状态信息
  8.     ClearChildViewState();
  9.     //创建一个带或不带指定数据源的控件层次结构
  10.     CreateControlHierarchy(true);
  11.     ChildControlsCreated = true;
  12.     TrackViewState();
  13. }

2.CreateControlHierarchy方法

 
 
 
 
  1. /**//// 
  2.  /// 创建一个带或不带指定数据源的控件层次结构
  3.  /// 
  4.  /// 指示是否要使用指定的数据源
  5.  //注意:当第二次执行数据绑定时,会执行两遍
  6.  private void CreateControlHierarchy(bool useDataSource)
  7.  {
  8.      IEnumerable dataSource = null;
  9.      int count = -1;
  10.      if (useDataSource == false)
  11.      {
  12.          // ViewState must have a non-null value for ItemCount because this is checked 
  13.          //  by CreateChildControls.
  14.          count = (int)ViewState["ItemCount"];
  15.          if (count != -1)
  16.          {
  17.              dataSource = new DummyDataSource(count);
  18.          }
  19.      }
  20.      else
  21.      {
  22.          dataSource = this.dataSource;
  23.      }
  24.      //根据项类型开始创建子控件
  25.      if (dataSource != null)
  26.      {
  27.          Table table = new Table();
  28.          Controls.Add(table);
  29.          //选中项索引
  30.          int selectedItemIndex = SelectedIndex;
  31.          //项索引
  32.          int index = 0;
  33.          //项数量
  34.          count = 0;
  35.          foreach (object dataItem in dataSource)
  36.          {
  37.              ListItemType itemType = ListItemType.Item;
  38.              if (index == selectedItemIndex)
  39.              {
  40.                 
  41.                  itemType = ListItemType.SelectedItem;
  42.              }
  43.              else if (index % 2 != 0)
  44.              {
  45.                  itemType = ListItemType.AlternatingItem;
  46.              }
  47.              //根据不同项索引创建样式
  48.              CreateItem(table, index, itemType, useDataSource, dataItem);
  49.              count++;
  50.              index++;
  51.          }
  52.      }
  53.      //执行绑定时执行时执行
  54.      if (useDataSource)
  55.      {
  56.          //保存项数量
  57.          ViewState["ItemCount"] = ((dataSource != null) ? count : -1);
  58.      }
  59.  }
  60.  //创建项
  61.  private TemplatedListItem CreateItem(Table table,  网站题目:ASP.NET数据绑定控件开发浅析
    当前路径:http://www.shufengxianlan.com/qtweb/news34/118334.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联