本篇将开始介绍如自定义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)定义控件成员属性
- #region 静态变量
 - private static readonly object EventSelectedIndexChanged = new object();
 - private static readonly object EventItemCreated = new object();
 - private static readonly object EventItemDataBound = new object();
 - private static readonly object EventItemCommand = new object();
 - #endregion
 - 成员变量#region 成员变量
 - private IEnumerable dataSource;
 - private TableItemStyle itemStyle;
 - private TableItemStyle alternatingItemStyle;
 - private TableItemStyle selectedItemStyle;
 - private ITemplate itemTemplate;
 - #endregion
 - 控件属性#region 控件属性
 - [
 - Category("Style"),
 - Description("交替项样式"),
 - DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
 - NotifyParentProperty(true),
 - PersistenceMode(PersistenceMode.InnerProperty),
 - ]
 - public virtual TableItemStyle AlternatingItemStyle
 - {
 - get
 - {
 - if (alternatingItemStyle == null)
 - {
 - alternatingItemStyle = new TableItemStyle();
 - if (IsTrackingViewState)
 - ((IStateManager)alternatingItemStyle).TrackViewState();
 - }
 - return alternatingItemStyle;
 - }
 - }
 - [
 - Category("Style"),
 - Description("一般项样式"),
 - DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
 - NotifyParentProperty(true),
 - PersistenceMode(PersistenceMode.InnerProperty),
 - ]
 - public virtual TableItemStyle ItemStyle
 - {
 - get
 - {
 - if (itemStyle == null)
 - {
 - itemStyle = new TableItemStyle();
 - if (IsTrackingViewState)
 - ((IStateManager)itemStyle).TrackViewState();
 - }
 - return itemStyle;
 - }
 - }
 - [
 - Category("Style"),
 - Description("选中项样式"),
 - DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
 - NotifyParentProperty(true),
 - PersistenceMode(PersistenceMode.InnerProperty),
 - ]
 - public virtual TableItemStyle SelectedItemStyle
 - {
 - get
 - {
 - if (selectedItemStyle == null)
 - {
 - selectedItemStyle = new TableItemStyle();
 - if (IsTrackingViewState)
 - ((IStateManager)selectedItemStyle).TrackViewState();
 - }
 - return selectedItemStyle;
 - }
 - }
 - [
 - Bindable(true),
 - Category("Appearance"),
 - DefaultValue(-1),
 - Description("The cell padding of the rendered table.")
 - ]
 - public virtual int CellPadding
 - {
 - get
 - {
 - if (ControlStyleCreated == false)
 - {
 - return -1;
 - }
 - return ((TableStyle)ControlStyle).CellPadding;
 - }
 - set
 - {
 - ((TableStyle)ControlStyle).CellPadding = value;
 - }
 - }
 - [
 - Bindable(true),
 - Category("Appearance"),
 - DefaultValue(0),
 - Description("The cell spacing of the rendered table.")
 - ]
 - public virtual int CellSpacing
 - {
 - get
 - {
 - if (ControlStyleCreated == false)
 - {
 - return 0;
 - }
 - return ((TableStyle)ControlStyle).CellSpacing;
 - }
 - set
 - {
 - ((TableStyle)ControlStyle).CellSpacing = value;
 - }
 - }
 - [
 - Bindable(true),
 - Category("Appearance"),
 - DefaultValue(GridLines.None),
 - Description("The grid lines to be shown in the rendered table.")
 - ]
 - public virtual GridLines GridLines
 - {
 - get
 - {
 - if (ControlStyleCreated == false)
 - {
 - return GridLines.None;
 - }
 - return ((TableStyle)ControlStyle).GridLines;
 - }
 - set
 - {
 - ((TableStyle)ControlStyle).GridLines = value;
 - }
 - }
 - [
 - Bindable(true),
 - Category("Data"),
 - DefaultValue(null),
 - Description("数据源"),
 - DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
 - ]
 - public IEnumerable DataSource
 - {
 - get
 - {
 - return dataSource;
 - }
 - set
 - {
 - dataSource = value;
 - }
 - }
 - [
 - Browsable(false),
 - DefaultValue(null),
 - Description("项模板"),
 - PersistenceMode(PersistenceMode.InnerProperty),
 - TemplateContainer(typeof(TemplatedListItem))
 - ]
 - public virtual ITemplate ItemTemplate
 - {
 - get
 - {
 - return itemTemplate;
 - }
 - set
 - {
 - itemTemplate = value;
 - }
 - }
 - [
 - Bindable(true),
 - DefaultValue(-1),
 - Description("选中项索引,默认为-1")
 - ]
 - public virtual int SelectedIndex
 - {
 - get
 - {
 - object o = ViewState["SelectedIndex"];
 - if (o != null)
 - return (int)o;
 - return -1;
 - }
 - set
 - {
 - if (value < -1)
 - {
 - throw new ArgumentOutOfRangeException();
 - }
 - //获取上次选中项
 - int oldSelectedIndex = SelectedIndex;
 - ViewState["SelectedIndex"] = value;
 - if (HasControls())
 - {
 - Table table = (Table)Controls[0];
 - TemplatedListItem item;
 - //第一次选中项不执行
 - if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
 - {
 - item = (TemplatedListItem)table.Rows[oldSelectedIndex];
 - //判断项类型,为了将选中项还原为数据项
 - if (item.ItemType != ListItemType.EditItem)
 - {
 - ListItemType itemType = ListItemType.Item;
 - if (oldSelectedIndex % 2 != 0)
 - itemType = ListItemType.AlternatingItem;
 - item.SetItemType(itemType);
 - }
 - }
 - //第一次执行此项,并一直执行
 - if ((value != -1) && (table.Rows.Count > value))
 - {
 - item = (TemplatedListItem)table.Rows[value];
 - item.SetItemType(ListItemType.SelectedItem);
 - }
 - }
 - }
 - }
 - #endregion
 
成员如下(可以看上面类图)
1.三个项样式和三个样式属性
2.公开DataSource数据源属性,一个模板属性
3.SelectedIndex索引属性
前面的相信大家都很容易明白,其中的三个项样式我们需要为其重写视图状态管理,不熟悉可以看以前的随笔,这里不再重复.
SelectedIndex属性比较复杂,这里重点介绍此属性
SelectedIndex索引属性默认为-1,
我给出了注释,在赋值前先记录下了上次的选中项,为恢复样式而做准备
- //获取上次选中项
 - int oldSelectedIndex = SelectedIndex;
 - ViewState["SelectedIndex"] = value;
 
当第一次更改SelectedIndex属性时只执行下列代码(将此项标记为选中项),因为初始化时的没有oldSelectedIndex,不需要恢复样式
- //第一次执行此项,并一直执行
 - if ((value != -1) && (table.Rows.Count > value))
 - {
 - item = (TemplatedListItem)table.Rows[value];
 - item.SetItemType(ListItemType.SelectedItem);
 - }
 
再次执行时,恢复oldSelectedIndex选中项样式
- //第一次选中项不执行
 - if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
 - {
 - item = (TemplatedListItem)table.Rows[oldSelectedIndex];
 - //判断项类型,为了将选中项还原为数据项
 - if (item.ItemType != ListItemType.EditItem)
 - {
 - ListItemType itemType = ListItemType.Item;
 - if (oldSelectedIndex % 2 != 0)
 - itemType = ListItemType.AlternatingItem;
 - item.SetItemType(itemType);
 - }
 - }
 
相信这样的解释你会明白
(2)定义控件成员事件
我们可以用上刚才我们声明的委托了,即然你定义了这么多事件,就该为其安排触发的先后.所以这个要特别注意,等下会再次提到.
- #region 事件
 - protected virtual void OnItemCommand(TemplatedListCommandEventArgs e)
 - {
 - TemplatedListCommandEventHandler onItemCommandHandler = (TemplatedListCommandEventHandler)Events[EventItemCommand];
 - if (onItemCommandHandler != null) onItemCommandHandler(this, e);
 - }
 - protected virtual void OnItemCreated(TemplatedListItemEventArgs e)
 - {
 - TemplatedListItemEventHandler onItemCreatedHandler = (TemplatedListItemEventHandler)Events[EventItemCreated];
 - if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
 - }
 - protected virtual void OnItemDataBound(TemplatedListItemEventArgs e)
 - {
 - TemplatedListItemEventHandler onItemDataBoundHandler = (TemplatedListItemEventHandler)Events[EventItemDataBound];
 - if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
 - }
 - protected virtual void OnSelectedIndexChanged(EventArgs e)
 - {
 - EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
 - if (handler != null) handler(this, e);
 - }
 - [
 - Category("Action"),
 - Description("Raised when a CommandEvent occurs within an item.")
 - ]
 - public event TemplatedListCommandEventHandler ItemCommand
 - {
 - add
 - {
 - Events.AddHandler(EventItemCommand, value);
 - }
 - remove
 - {
 - Events.RemoveHandler(EventItemCommand, value);
 - }
 - }
 - [
 - Category("Behavior"),
 - Description("Raised when an item is created and is ready for customization.")
 - ]
 - public event TemplatedListItemEventHandler ItemCreated
 - {
 - add
 - {
 - Events.AddHandler(EventItemCreated, value);
 - }
 - remove
 - {
 - Events.RemoveHandler(EventItemCreated, value);
 - }
 - }
 - [
 - Category("Behavior"),
 - Description("Raised when an item is data-bound.")
 - ]
 - public event TemplatedListItemEventHandler ItemDataBound
 - {
 - add
 - {
 - Events.AddHandler(EventItemDataBound, value);
 - }
 - remove
 - {
 - Events.RemoveHandler(EventItemDataBound, value);
 - }
 - }
 - [
 - Category("Action"),
 - Description("Raised when the SelectedIndex property has changed.")
 - ]
 - public event EventHandler SelectedIndexChanged
 - {
 - add
 - {
 - Events.AddHandler(EventSelectedIndexChanged, value);
 - }
 - remove
 - {
 - Events.RemoveHandler(EventSelectedIndexChanged, value);
 - }
 - }
 - #endregion
 
(3)关键实现
我们为控件提供了这么多东西,剩下的事情就是要真正去实现功能了
1.重写DataBind方法
当控件绑定数据时首先会执行此方法触发DataBinding事件
- //控件执行绑定时执行
 - public override void DataBind()
 - {
 - base.OnDataBinding(EventArgs.Empty);
 - //移除控件
 - Controls.Clear();
 - //清除视图状态信息
 - ClearChildViewState();
 - //创建一个带或不带指定数据源的控件层次结构
 - CreateControlHierarchy(true);
 - ChildControlsCreated = true;
 - TrackViewState();
 - }
 
2.CreateControlHierarchy方法
- /**////
 - /// 创建一个带或不带指定数据源的控件层次结构
 - ///
 - /// 指示是否要使用指定的数据源
 - //注意:当第二次执行数据绑定时,会执行两遍
 - private void CreateControlHierarchy(bool useDataSource)
 - {
 - IEnumerable dataSource = null;
 - int count = -1;
 - if (useDataSource == false)
 - {
 - // ViewState must have a non-null value for ItemCount because this is checked
 - // by CreateChildControls.
 - count = (int)ViewState["ItemCount"];
 - if (count != -1)
 - {
 - dataSource = new DummyDataSource(count);
 - }
 - }
 - else
 - {
 - dataSource = this.dataSource;
 - }
 - //根据项类型开始创建子控件
 - if (dataSource != null)
 - {
 - Table table = new Table();
 - Controls.Add(table);
 - //选中项索引
 - int selectedItemIndex = SelectedIndex;
 - //项索引
 - int index = 0;
 - //项数量
 - count = 0;
 - foreach (object dataItem in dataSource)
 - {
 - ListItemType itemType = ListItemType.Item;
 - if (index == selectedItemIndex)
 - {
 - itemType = ListItemType.SelectedItem;
 - }
 - else if (index % 2 != 0)
 - {
 - itemType = ListItemType.AlternatingItem;
 - }
 - //根据不同项索引创建样式
 - CreateItem(table, index, itemType, useDataSource, dataItem);
 - count++;
 - index++;
 - }
 - }
 - //执行绑定时执行时执行
 - if (useDataSource)
 - {
 - //保存项数量
 - ViewState["ItemCount"] = ((dataSource != null) ? count : -1);
 - }
 - }
 - //创建项
 - private TemplatedListItem CreateItem(Table table,
 文章名称:ASP.NET数据绑定控件开发浅析
转载来于:http://www.csdahua.cn/qtweb/news34/118334.html网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网