ASP.NET服务器控件开发简介: ComboBox [开放源代码]

简介

我在Web项目的开发过程中很多时候都要用到ComboBox,找了很多类似的控件来用发现都不尽如人意,我所希望的能够在WEB上使用的ComboBox应该就是在DropDownList的功能上加入了文本输入功能,我个人比较看重的一点就是下拉列表应该可以伸展到浏览器之外,然而目前大多数的ComboBox要么是用DIV来显示选择项,要么就是用TextBox+ListBox,DIV的方式会不能伸展到浏览器之外,而TextBox+ListBox方式ListBox占用页面空间。后来发现了A DHTML combo box , 于是决定基于此HTC开发一个ASP.NET服务器控件.

ComboBoxDemo.gif

关键类设计

  • 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);
                }

            }

        }

三种使用方式

  1. 编程方式:

     

    for ( int  i = 1 ; i  <   10 ; i ++ )
                    
    {
                        ComboItem item 
    = new ComboItem("Item"+i.ToString());
                        ComboBox1.Items.Add(item);
                    }

     

  2. 数据绑定方式

     

    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();

     

  3. 页面直接申明方式

     

    < 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

声明

欢迎转载,转载请注明出处。发布到商业性电子或者平面媒体需征得作者同意。
本组件已经由本人在CodeProject.com发布: Custom ComboBox server control for ASP.NET

转载于:https://www.cnblogs.com/mcsm/articles/1897877.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值