簡介
我在Web項目的開發(fā)過程中很多時候都要用到ComboBox,找了很多類似的控件來用發(fā)現(xiàn)都不盡如人意,我所希望的能夠在WEB上使用的ComboBox應(yīng)該就是在DropDownList的功能上加入了文本輸入功能,我個人比較看重的一點就是下拉列表應(yīng)該可以伸展到瀏覽器之外,然而目前大多數(shù)的ComboBox要么是用DIV來顯示選擇項,要么就是用TextBox+ListBox,DIV的方式會不能伸展到瀏覽器之外,而TextBox+ListBox方式ListBox占用頁面空間。后來發(fā)現(xiàn)了A DHTML combo box , 于是決定基于此HTC開發(fā)一個ASP.NET服務(wù)器控件.
關(guān)鍵類設(shè)計
- ComboBox : 關(guān)鍵是有一個Text屬性獲取控件值,沒有SelectedIndexChanged事件(我覺得該事件對ComboBox來說不是很重要,當然你也可以根據(jù)你自己的需要增加對此事件的支持),Items屬性當然是必不可少的;
- ComboItem : 相對于ListItem來說我沒有設(shè)計Value屬性;
- ComboItemCollection : 這是ComboItem的集合類,實現(xiàn)了ICollection接口,其功能類似ListItemCollection。
實現(xiàn)ViewState
實現(xiàn)ViewState是我個人覺得最有趣的部分,根據(jù)類的層次結(jié)構(gòu),先看看ComboItem如何實現(xiàn)ViewState,其實很簡單,就是實現(xiàn)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,同樣實現(xiàn)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()方法逐項保存視圖狀態(tài),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()方法保存了基類的視圖狀態(tài),同時將Items屬性和Text屬性保存到視圖狀態(tài)中,而LoadViewState(object savedState)方法則實現(xiàn)還原。
實現(xiàn)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;
} 實現(xiàn)數(shù)據(jù)綁定
如何像DropDownList一樣實現(xiàn)數(shù)據(jù)綁定,也是我十分關(guān)心的部分。關(guān)鍵是重寫OnDataBinding方法,同時增加了一個類DataSourceHelper來解析數(shù)據(jù)源。
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);
}
- 數(shù)據(jù)綁定方式
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>
源代碼下載
http://files.cnblogs.com/bestcomy/WebControlTest.rar
聲明