ASP.NET服务器控件开发简介: ComboBox


源代码下载: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>


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3