soho网站建设,个人主页怎么找,合肥品牌设计,wordpress怎么设置语言设置中文上两篇讨论了基本数据绑定控件的实现步骤#xff0c;基本上我们按着步骤来就可以做出简单的数据绑定控件了。过年前在看DataGrid的实现#xff0c;本来想写这个的#xff0c;但2.0出了GridView了#xff0c;再说表格控件实现比较复杂#xff0c;所以先放着。我们一起打开M…上两篇讨论了基本数据绑定控件的实现步骤基本上我们按着步骤来就可以做出简单的数据绑定控件了。过年前在看DataGrid的实现本来想写这个的但2.0出了GridView了再说表格控件实现比较复杂所以先放着。我们一起打开MSDN来看点别的当然主题还是离不开数据绑定控件。 一.数据绑定控件的模板打开MSDN一看我们会发现DataList和DataGrid都不是直接继承自WebControl类的而是继承自一个叫BaseDataList的类。唯独Repeater是直接继承自WebControl类的Repeater的简单也就代表定义样式的灵活。DataList和DataGrid则是规规矩矩的经过加工的列表控件。 再看看BaseDataList其是一个抽象类。其为数据列表控件提供了公共的列表样式属性布局。 并定义了两个抽象方法CreateControlHierarchy方法和PrepareControlHierarchy方法留给子类实现这两个方法上两篇我们都认识过了。主要是因为定义了不同模板和样式。可以说是一个典型的模板类如果你也需要写一个基于表格的数据绑定控件可以跳过从WebControl继承优先考虑从BaseDataList开始。如果这个抽象类无法满足需求那你便放弃他。自己定义一个抽象类定义公共的属性方法等这样对以后的扩展有利。当然一般情况下我们的需求就够用了。 这里我们可以结合设计模式的学习得出的一个结论把公用的成员抽象出来 说到这里我们漏掉了一个数据绑定控件的一个大话题,列表绑定控件如DropDownList,ListBox,CheckBoxList等 下面来看看Repeater版本的DropDownList asp:SqlDataSource IDSqlDataSource1 runatserver ConnectionString%$ ConnectionStrings:NorthwindConnectionString % SelectCommandSELECT top 3 [ProductID], [ProductName] FROM [Alphabetical list of products] /asp:SqlDataSource asp:Repeater IDRepeater1 runatserver DataSourceIDSqlDataSource1 HeaderTemplate select idSelect1 /HeaderTemplate ItemTemplate option%# Eval(ProductName)%/option /ItemTemplate FooterTemplate /select /FooterTemplate /asp:Repeater asp:DropDownList IDDropDownList2 DataTextFieldProductName runatserver DataSourceIDSqlDataSource1 /asp:DropDownList 其实现效果和DropDownList一模一样。Repeater灵活但这种做法并不优雅。列表控件也有一个抽象类ListControl。列表控件从此类派生。2.0新加了一个控件BulletedList.相信大家对这几个控件是绝对的很熟悉常与其打交道我们就一起来看看他们是怎么实现的。 System.Web.UI.WebControls.ListControl System.Web.UI.WebControls.BulletedList System.Web.UI.WebControls.CheckBoxList System.Web.UI.WebControls.DropDownList System.Web.UI.WebControls.ListBox System.Web.UI.WebControls.RadioButtonList 二.列表绑定控件 (1)抽象类ListControl及相关类 像BaseDataList一样ListControl也为列表控件提供的公共成员。根据我们的平时使用列表控件都具有以下功能 1.提供DataTextFormatString属性可以对绑定数据文本进行格式化2.提供数据源属性DataSource和DataMember属性 3.提供DataTextField属性和DataValueField属性分别为列表控件数据项提供列表显示文本和值的数据源字段 4.提供了ListItem代表列表控件的数据项此需要实现一个迭代比数据绑定的做法更加灵活 5.提供ListItemCollection代表ListItem项集合 6.提供SelectedIndex属性和SelectedItem属性进行索引 7.提供SelectedIndexChanged事件并实现IEditableTextControl接口实现TextChanged事件 8.提供AutoPostBack属性当用户更改列表中的选定内容时可以向服务器自动回发 其他还有2.0新增的一些功能就别再介绍了大家可以看看MSDN 做了上面这么多工作接下来的工作就比较的轻松了。(2)具体子类控件 根据功能的不同可以把内置的5个控件归为三类为什么这么分可以看看此类图 1.ListBox和DropDownList 2.CheckBoxList和RadioButtonList 3.BulletedList 这三类控件从ListControl派生并根据自身功能的不同进行了一些调整第一类实现最简单ListControl本身为其默认实现了很多其只需要根据自身需求重写几个方法就可以了 第二类控件为复合控件其实现了IRepeatInfoUser接口此接口任何重复项列表的列表控件实现的属性和方法大多为空实现主要实现了RenderItem方法。其还定义了控件的布局和现实方法并直接重写了Render方法然后用RepeatInfo类来根据RepeatDirection的不同呈现项信息 第三类控件为新增控件显示一个项列表 要看出不同则可以根据生成的html代码进行比较(3)具体实现 1.简单实现一个DropDownList可能就LoadPostData方法稍微复杂点其他的应该都没什么public class CustomDropDownList : ListControl, IPostBackDataHandler { [DefaultValue(0), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override int SelectedIndex { get { int selectedIndex base.SelectedIndex; if ((selectedIndex 0) (this.Items.Count 0)) { this.Items[0].Selected true; selectedIndex 0; } return selectedIndex; } set { base.SelectedIndex value; } } protected override void AddAttributesToRender(HtmlTextWriter writer) { string uniqueID this.UniqueID; if (uniqueID ! null) { writer.AddAttribute(HtmlTextWriterAttribute.Name, uniqueID); } base.AddAttributesToRender(writer); } protected override ControlCollection CreateControlCollection() { base.CreateControlCollection(); } IPostBackDataHandler 成员#region IPostBackDataHandler 成员 public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) { string[] values postCollection.GetValues(postDataKey); this.EnsureDataBound(); if (values ! null) { ListItem selectitem Items.FindByValue(values[0]); int selectedIndex this.Items.IndexOf(selectitem); if (this.SelectedIndex ! selectedIndex) { //设置selected属性 base.SetPostDataSelection(selectedIndex); return true; } } return false; } public void RaisePostDataChangedEvent() { OnSelectedIndexChanged(EventArgs.Empty); } #endregion } 2. 第二类控件比较复杂如CheckBoxList是一个CheckBox项列表其实现了IRepeatInfoUser接口实现此接口的有如CheckBoxList、DataList、RadioButtonList。下面说明实现步骤 public class CustomCheckBoxList: ListControl, IRepeatInfoUser, INamingContainer, IPostBackDataHandler { } 2.1 实现IRepeatInfoUser接口IRepeatInfoUser接口定义了重复项列表的列表控件实现的属性和方法RenderItem方法用于呈现其中的一项信息。如下代码protected virtual void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer) { ListItem item Items[repeatIndex]; check_box.Attributes.Clear(); if (item.Attributes.Count0) { foreach (string text in item.Attributes.Keys) { this.check_box.Attributes[text] item.Attributes[text]; } } check_box.ID repeatIndex.ToString(CultureInfo.InvariantCulture); check_box.Text item.Text; check_box.Checked item.Selected; check_box.TextAlign TextAlign; check_box.Enabled Enabled; check_box.RenderControl(writer); } 2.2呈现 CheckBoxList为复合控件本该重写TagKey属性和CreateChildControls方法等而是在构造函数中添加了CheckBox。.net提供了一个RepeatInfo的辅助类其与实现IRepeatInfoUser接口的控件搭配使用此类的RenderRepeater方法会调用CheckBoxList的RenderItem方法然后根据控件的布局自上而下呈现项列表信息。要区分清楚RenderItem方法位呈现一条项信息RenderRepeater方法是呈现列表信息此实现过程在Render方法中实现而非RenderContents方法. protected override void Render(HtmlTextWriter writer) { RepeatInfo ri new RepeatInfo(); //设置呈现布局 ri.RepeatColumns RepeatColumns; ri.RepeatDirection RepeatDirection; ri.RepeatLayout RepeatLayout; short ti 0; if (TabIndex ! 0) { check_box.TabIndex TabIndex; ti TabIndex; TabIndex 0; } //呈现项列表信息 ri.RenderRepeater(writer, this, ControlStyle, this); if (ti ! 0) TabIndex ti; } 2.3预呈现将CheckBoxList中属性赋给子控件在呈现之前执行必要的预呈现 protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); check_box.AutoPostBack AutoPostBack; check_box.CausesValidation CausesValidation; check_box.ValidationGroup ValidationGroup; //自动回传 for (int i 0; i Items.Count; i) { if (Items[i].Selected) { check_box.ID i.ToString(CultureInfo.InvariantCulture); Page.RegisterRequiresPostBack(check_box); } } } 2.4实现IPostBackDataHandler当选中时,postCollection[postDataKey]为on protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) { int checkbox -1; try { string id postDataKey.Substring(ClientID.Length 1); if (Char.IsDigit(id[0])) checkbox Int32.Parse(id, CultureInfo.InvariantCulture); } catch { return false; } if (checkbox -1) return false; string val postCollection[postDataKey]; bool ischecked val on; ListItem item Items[checkbox]; if (item.Selected ! ischecked) { item.Selected ischecked; return true; } return false; } 到这里实现的就差不多了BulletedList的实现就不再写了。总之控件在不同生命周期完成了不同的事,一步一步的下来就成就了一个控件。在模板控件中使用的注意点: 记得我以前在用radiobuttonlist时遇到过一个问题.我想在一个表格中实现一个很简单的效果如下图 刚开始我以为很简单把radiobutton放在Repeater里面radiobutton的GroupName是跟着ID变的。 却忘了服务器控件进了Repeater模板里面其ID属性就会重命名这带来了很多的不便。于是我想用radiobuttonlistradiobuttonlist呈现后则为一个表格不够灵活我就不得不重写其布局。 更讨厌的是由于radiobutton需要Text属性其不同于DropDownList(其实DropDownList和ListBox才算的上是名副其实的列表控件),所以无法将input作为父标签为了共享WebControl成员只得多加个span标签其重写了最后呈现如下span stylecolor:Red;input idRadioButton1 typeradio nameRadioButton1 valueRadioButton1 /label forRadioButton1测试/label/span 虽然2.0中添加了InputAttributes和LabelAttributes集合属性但name属性已经定死了。或者就是再添加一个重复的name属性或者就是再重新写一个这个算不算是缺点? 感觉用起来就是不顺心。 感觉越到下面问题越多了如果有错误还请指出。这次主要学习下如何自定义列表控件接着打算开始记录下2.0新增的数据源控件如何实现。示例代码 转载于:https://www.cnblogs.com/hunterzou/archive/2008/12/19/1358569.html