|
源代码网推荐
源代码下载:http://file.ddvip.com/2008_11/1227927321_ddvip_9159.rar 简介
我在Web项目的开发过程中很多时候都要用到ComboBox,找了很多类似的控件来用发现都不尽如人意,我所希望的能够在WEB上使用的ComboBox应该就是在DropDownList的功能上加入了文本输入功能,我个人比较看重的一点就是下拉列表应该可以伸展到浏览器之外,然而目前大多数的ComboBox要么是用DIV来显示选择项,要么就是用TextBox+ListBox,DIV的方式会不能伸展到浏览器之外,而TextBox+ListBox方式ListBox占用页面空间。后来发现了A DHTML combo box , 于是决定基于此HTC开发一个ASP.NET服务器控件.
关键类设计
ComboBox : 关键是有一个Text属性获取控件值,没有SelectedIndexChanged事件(我觉得该事件对ComboBox来说不是很重要,当然你也可以根据你自己的需要增加对此事件的支持),Items属性当然是必不可少的;
ComboItem : 相对于ListItem来说我没有设计Value属性;
ComboItemCollection : 这是ComboItem的集合类,实现了ICollection接口,其功能类似ListItemCollection。
实现ViewState
实现ViewState是我个人觉得最有趣的部分,根据类的层次结构,先看看ComboItem如何实现ViewState,其实很简单,就是实现System.Web.UI.IStateManager接口:
public void TrackViewState() { this._IsTrackingViewState = true; } public bool IsTrackingViewState { get { return this._IsTrackingViewState; } } public object SaveViewState() { return new Pair(this._text,this._selected); } public void LoadViewState(object state) { if(state!=null && state is Pair) { Pair p = (Pair)state; this._text = (string)p.First; this._selected = (bool)p.Second; } }
SaveViewState()方法保存了ComboItem的Text和Selected属性,而LoadViewState(object state)则还原了这两个属性。
接着看看ComboItemCollection,同样实现IStateManager接口:
public void TrackViewState() { this._IsTrackingViewState = true; for(int i=0; i < this._items.Count; i++) { ((IStateManager)this[i]).TrackViewState(); } } public bool IsTrackingViewState { get { return this._IsTrackingViewState; } } public object SaveViewState() { ArrayList list1 = new ArrayList(); ArrayList list2 = new ArrayList(); for (int num3 = 0; num3 < this.Count; num3++) { object obj1 = ((IStateManager)this[num3]).SaveViewState(); if (obj1 != null) { list1.Add(num3); list2.Add(obj1); } } if (list1.Count > 0) { return new Pair(list1, list2); } return null; } public void LoadViewState(object state) { if (state == null) { return; } if (state is Pair) { Pair pair1 = (Pair) state; ArrayList list1 = (ArrayList) pair1.First; ArrayList list2 = (ArrayList) pair1.Second; for (int num1 = 0; num1 < list1.Count; num1++) { int num2 = (int) list1[num1]; if (num2 < this.Count) { ((IStateManager)this[num2]).LoadViewState(list2[num1]); } else { ComboItem item1 = new ComboItem(); ((IStateManager)item1).LoadViewState(list2[num1]); this.Add(item1); } } } } SaveViewState()方法逐项保存视图状态,LoadViewState(object state) 逐项还原。
最后看看ComboBox,重写了如下一些方法:
protected override void TrackViewState() { base.TrackViewState (); ((IStateManager)this.Items).TrackViewState(); } protected override object SaveViewState() { object obj1 = base.SaveViewState(); object obj2 = ((IStateManager)this.Items).SaveViewState(); object obj3 = this.Text; if(obj1==null && obj2==null && obj3==null) return null; return new Triplet(obj1,obj2,obj3); } protected override void LoadViewState(object savedState) { if(savedState!=null) { Triplet state = (Triplet)savedState; base.LoadViewState(state.First); ((IStateManager)this.Items).LoadViewState(state.Second); _text = (string)state.Third; } }
SaveViewState()方法保存了基类的视图状态,同时将Items属性和Text属性保存到视图状态中,而LoadViewState(object savedState)方法则实现还原。
实现IPostBackDataHandler接口
public void RaisePostDataChangedEvent() { } public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) { string[] textArray1 = postCollection.GetValues(postDataKey); if (textArray1 != null) { this.ClearSelection(); ComboItem item = this.FindByText(textArray1[0]); if(item != null) { item.Selected = true; } _text = textArray1[0]; } return false; } 实现数据绑定
如何像DropDownList一样实现数据绑定,也是我十分关心的部分。关键是重写OnDataBinding方法,同时增加了一个类DataSourceHelper来解析数据源。
protected override void OnDataBinding(EventArgs e) { base.OnDataBinding (e); IEnumerable enumerable1 = DataSourceHelper.GetResolvedDataSource(this.DataSource, this.DataMember); if (enumerable1 != null) { this.Items.Clear(); foreach (object obj1 in enumerable1) { ComboItem item = new ComboItem(); if(this.DataTextField != string.Empty) item.Text = DataBinder.GetPropertyValue(obj1,this.DataTextField,null); else item.Text = obj1.ToString(); this.Items.Add(item); } } }
三种使用方式
编程方式:
for(int i=1; i < 10; i++) { ComboItem item = new ComboItem("Item"+i.ToString()); ComboBox1.Items.Add(item); }
数据绑定方式
DataTable dt = new DataTable(); dt.Columns.Add("text", typeof(string)); for(int i=1; i < 10; i++) { DataRow ndr = dt.NewRow(); ndr["text"] = "Item" + i.ToString(); dt.Rows.Add(ndr); } ComboBox3.DataSource = dt.DefaultView; ComboBox3.DataTextField = "text"; ComboBox3.DataBind();
页面直接申明方式
<bestcomy:ComboBox id="ComboBox2" runat="server" Width="120px"> <BESTCOMY:COMBOITEM Text="Item1"></BESTCOMY:COMBOITEM> <BESTCOMY:COMBOITEM Text="Item2"></BESTCOMY:COMBOITEM> <BESTCOMY:COMBOITEM Text="Item3" Selected="true"></BESTCOMY:COMBOITEM> <BESTCOMY:COMBOITEM Text="Item4"></BESTCOMY:COMBOITEM> </bestcomy:ComboBox>
本文作者:未知
源代码网供稿. |