看了不少有关aspnet自定义控件的文章,一直想练练手。以前在博客园也看到了Bestcomy实现的代码,感觉实现起来稍微复杂了点,而且控件的大小和定位也有些问题。本控件主要是参考Bestcomy的思路利用htc控制客户端显示,但是服务器端代码主要参考了微软的相关代码直接从DropDownList继承生成新的控件。
代码很简单,只有3个文件,两个cs文件和一个修改过的htc文件。
ComboBox.cs
1
using
System;
2 using System.ComponentModel;
3 using System.Collections;
4 using System.IO;
5 using System.Globalization;
6 using System.Resources;
7 using System.Web;
8 using System.Web.UI;
9 using System.Web.UI.WebControls;
10 using System.Reflection;
11 using System.Drawing;
12 using System.Collections.Specialized;
13
14 [assembly:TagPrefix( " Zondysoft.EGov.WebControls " , " Zondysoft " )]
15 namespace Zondysoft.EGov.WebControls
16 {
17 /// <summary>
18 /// ComboBox 的摘要说明。
19 /// </summary>
20 [ToolboxData( " <{0}:ComboBox runat=server></{0}:ComboBox> " ),Designer( typeof (ComboBoxDesigner))]
21 public class ComboBox : DropDownList, IPostBackDataHandler
22 {
23 public ComboBox()
24 {
25
26 }
27
28 [Bindable( true ),Category( " Appearance " ),DefaultValue( "" )]
29 public string Text
30 {
31 get
32 {
33 if (ViewState[ " Text " ] == null )
34 {
35 return string .Empty;
36 }
37 else
38 {
39 return ViewState[ " Text " ].ToString();
40 }
41 }
42 set
43 {
44 ViewState[ " Text " ] = value;
45 if ( this .Items.Count > 0 )
46 {
47 int num = this .FindByTextInternal(value);
48 if ( this .SelectedIndex != num)
49 {
50 this .SelectedIndex = num;
51 }
52 }
53 }
54 }
55
56 /// <summary>
57 /// 将此控件呈现给指定的输出参数。
58 /// </summary>
59 /// <param name="output"> 要写出到的 HTML 编写器 </param>
60 protected override void Render(HtmlTextWriter write)
61 {
62 write.Write( " <?XML:NAMESPACE PREFIX=DEADBEEF /> " + Environment.NewLine);
63 write.Write( " <?IMPORT NAMESPACE=DEADBEEF IMPLEMENTATION=\ " combobox.htc\ " /> " + Environment.NewLine);
64 this .AddAttributesToRender(write);
65 write.RenderBeginTag( " DEADBEEF:COMBOBOX " );
66 this .RenderContents(write);
67 write.RenderEndTag();
68 }
69
70 protected override void RenderContents(HtmlTextWriter writer)
71 {
72 ListItemCollection items = this .Items;
73 int count = this .Items.Count;
74 bool flag = false ;
75 if (count > 0 )
76 {
77 for ( int i = 0 ; i < count; i ++ )
78 {
79 ListItem item = items[i];
80 writer.WriteBeginTag( " option " );
81 if (item.Selected)
82 {
83 if (flag)
84 {
85 throw new HttpException( " Cant_Multiselect_In_DropDownList " );
86 }
87 flag = true ;
88 writer.WriteAttribute( " selected " , " selected " , false );
89 }
90 writer.WriteAttribute( " value " , item.Value, true );
91 writer.Write( ' > ' );
92 HttpUtility.HtmlEncode(item.Text, writer);
93 writer.WriteEndTag( " option " );
94 writer.WriteLine();
95 }
96 }
97 }
98
99 protected override void AddAttributesToRender(HtmlTextWriter writer)
100 {
101 if ( this .Page != null )
102 {
103 this .Page.VerifyRenderingInServerForm( this );
104 }
105
106 writer.AddAttribute( " id " , this .UniqueID);
107 writer.AddAttribute( " name " , this .UniqueID);
108 writer.AddAttribute( " text " , this .Text, true );
109 writer.AddAttribute( " index " , this .SelectedIndex.ToString());
110 writer.AddAttribute( " width " , this .Width.Value.ToString());
111
112 if ( this .AutoPostBack && ( this .Page != null ))
113 {
114 string postBackClientEvent = this .Page.GetPostBackClientEvent( this , "" );
115 string str2 = base .Attributes[ " onchange " ];
116 if (str2 != null )
117 {
118 postBackClientEvent = str2 + postBackClientEvent;
119 base .Attributes.Remove( " onchange " );
120 }
121 writer.AddAttribute(HtmlTextWriterAttribute.Onchange, postBackClientEvent);
122 writer.AddAttribute( " language " , " javascript " );
123 }
124 }
125
126 #region IPostBackDataHandler
127
128 private int FindByTextInternal( string text)
129 {
130 int num = 0 ;
131 foreach (ListItem item in this .Items)
132 {
133 if (item.Text.Equals(text))
134 {
135 return num;
136 }
137 num ++ ;
138 }
139 return - 1 ;
140 }
141
142 bool IPostBackDataHandler.LoadPostData( string postDataKey, NameValueCollection postCollection)
143 {
144 string [] values = postCollection.GetValues(postDataKey);
145 if (values != null )
146 {
147 this .Text = values[ 0 ];
148 }
149 string controlId = this .Page.Request.Form[ " __EVENTTARGET " ];
150 if (controlId != null && controlId != string .Empty)
151 {
152 if ( this .Page.FindControl(controlId) is ComboBox)
153 {
154 int num = this .FindByTextInternal(values[ 0 ]);
155 if ( this .SelectedIndex != num)
156 {
157 this .SelectedIndex = num;
158 this .Text = this .SelectedItem.Text;
159 }
160 return true ;
161 }
162 }
163 return false ;
164 }
165
166 void IPostBackDataHandler.RaisePostDataChangedEvent()
167 {
168 this .OnSelectedIndexChanged(EventArgs.Empty);
169 }
170
171 #endregion
172 }
173 }
2 using System.ComponentModel;
3 using System.Collections;
4 using System.IO;
5 using System.Globalization;
6 using System.Resources;
7 using System.Web;
8 using System.Web.UI;
9 using System.Web.UI.WebControls;
10 using System.Reflection;
11 using System.Drawing;
12 using System.Collections.Specialized;
13
14 [assembly:TagPrefix( " Zondysoft.EGov.WebControls " , " Zondysoft " )]
15 namespace Zondysoft.EGov.WebControls
16 {
17 /// <summary>
18 /// ComboBox 的摘要说明。
19 /// </summary>
20 [ToolboxData( " <{0}:ComboBox runat=server></{0}:ComboBox> " ),Designer( typeof (ComboBoxDesigner))]
21 public class ComboBox : DropDownList, IPostBackDataHandler
22 {
23 public ComboBox()
24 {
25
26 }
27
28 [Bindable( true ),Category( " Appearance " ),DefaultValue( "" )]
29 public string Text
30 {
31 get
32 {
33 if (ViewState[ " Text " ] == null )
34 {
35 return string .Empty;
36 }
37 else
38 {
39 return ViewState[ " Text " ].ToString();
40 }
41 }
42 set
43 {
44 ViewState[ " Text " ] = value;
45 if ( this .Items.Count > 0 )
46 {
47 int num = this .FindByTextInternal(value);
48 if ( this .SelectedIndex != num)
49 {
50 this .SelectedIndex = num;
51 }
52 }
53 }
54 }
55
56 /// <summary>
57 /// 将此控件呈现给指定的输出参数。
58 /// </summary>
59 /// <param name="output"> 要写出到的 HTML 编写器 </param>
60 protected override void Render(HtmlTextWriter write)
61 {
62 write.Write( " <?XML:NAMESPACE PREFIX=DEADBEEF /> " + Environment.NewLine);
63 write.Write( " <?IMPORT NAMESPACE=DEADBEEF IMPLEMENTATION=\ " combobox.htc\ " /> " + Environment.NewLine);
64 this .AddAttributesToRender(write);
65 write.RenderBeginTag( " DEADBEEF:COMBOBOX " );
66 this .RenderContents(write);
67 write.RenderEndTag();
68 }
69
70 protected override void RenderContents(HtmlTextWriter writer)
71 {
72 ListItemCollection items = this .Items;
73 int count = this .Items.Count;
74 bool flag = false ;
75 if (count > 0 )
76 {
77 for ( int i = 0 ; i < count; i ++ )
78 {
79 ListItem item = items[i];
80 writer.WriteBeginTag( " option " );
81 if (item.Selected)
82 {
83 if (flag)
84 {
85 throw new HttpException( " Cant_Multiselect_In_DropDownList " );
86 }
87 flag = true ;
88 writer.WriteAttribute( " selected " , " selected " , false );
89 }
90 writer.WriteAttribute( " value " , item.Value, true );
91 writer.Write( ' > ' );
92 HttpUtility.HtmlEncode(item.Text, writer);
93 writer.WriteEndTag( " option " );
94 writer.WriteLine();
95 }
96 }
97 }
98
99 protected override void AddAttributesToRender(HtmlTextWriter writer)
100 {
101 if ( this .Page != null )
102 {
103 this .Page.VerifyRenderingInServerForm( this );
104 }
105
106 writer.AddAttribute( " id " , this .UniqueID);
107 writer.AddAttribute( " name " , this .UniqueID);
108 writer.AddAttribute( " text " , this .Text, true );
109 writer.AddAttribute( " index " , this .SelectedIndex.ToString());
110 writer.AddAttribute( " width " , this .Width.Value.ToString());
111
112 if ( this .AutoPostBack && ( this .Page != null ))
113 {
114 string postBackClientEvent = this .Page.GetPostBackClientEvent( this , "" );
115 string str2 = base .Attributes[ " onchange " ];
116 if (str2 != null )
117 {
118 postBackClientEvent = str2 + postBackClientEvent;
119 base .Attributes.Remove( " onchange " );
120 }
121 writer.AddAttribute(HtmlTextWriterAttribute.Onchange, postBackClientEvent);
122 writer.AddAttribute( " language " , " javascript " );
123 }
124 }
125
126 #region IPostBackDataHandler
127
128 private int FindByTextInternal( string text)
129 {
130 int num = 0 ;
131 foreach (ListItem item in this .Items)
132 {
133 if (item.Text.Equals(text))
134 {
135 return num;
136 }
137 num ++ ;
138 }
139 return - 1 ;
140 }
141
142 bool IPostBackDataHandler.LoadPostData( string postDataKey, NameValueCollection postCollection)
143 {
144 string [] values = postCollection.GetValues(postDataKey);
145 if (values != null )
146 {
147 this .Text = values[ 0 ];
148 }
149 string controlId = this .Page.Request.Form[ " __EVENTTARGET " ];
150 if (controlId != null && controlId != string .Empty)
151 {
152 if ( this .Page.FindControl(controlId) is ComboBox)
153 {
154 int num = this .FindByTextInternal(values[ 0 ]);
155 if ( this .SelectedIndex != num)
156 {
157 this .SelectedIndex = num;
158 this .Text = this .SelectedItem.Text;
159 }
160 return true ;
161 }
162 }
163 return false ;
164 }
165
166 void IPostBackDataHandler.RaisePostDataChangedEvent()
167 {
168 this .OnSelectedIndexChanged(EventArgs.Empty);
169 }
170
171 #endregion
172 }
173 }
ComboBoxDesigner.cs
1
using
System;
2 using System.IO;
3 using System.Web.UI;
4 using System.Web.UI.Design;
5 using System.Web.UI.WebControls;
6 using System.Web.UI.Design.WebControls;
7
8 namespace Zondysoft.EGov.WebControls
9 {
10 /// <summary>
11 /// 设计时支持
12 /// </summary>
13 public class ComboBoxDesigner : ControlDesigner
14 {
15 /// <summary>
16 /// 获取设计时用于表示控件的 HTML
17 /// </summary>
18 /// <returns></returns>
19 public override string GetDesignTimeHtml()
20 {
21 ComboBox comboBox = (ComboBox) base .Component;
22 DropDownList dropDownList = new DropDownList();
23 if (comboBox.Items.Count == 0 && comboBox.Text == string .Empty)
24 {
25 dropDownList.Items.Add( new ListItem( " 未绑定 " ));
26 }
27 else
28 {
29 dropDownList.Items.Add(comboBox.Text);
30 foreach (ListItem item in comboBox.Items)
31 {
32 dropDownList.Items.Add(item);
33 }
34 dropDownList.SelectedIndex = 0 ;
35 }
36 dropDownList.Width = comboBox.Width;
37 StringWriter sw = new StringWriter();
38 HtmlTextWriter tw = new HtmlTextWriter(sw);
39 dropDownList.RenderControl(tw);
40 return sw.ToString();
41 }
42 }
43 }
2 using System.IO;
3 using System.Web.UI;
4 using System.Web.UI.Design;
5 using System.Web.UI.WebControls;
6 using System.Web.UI.Design.WebControls;
7
8 namespace Zondysoft.EGov.WebControls
9 {
10 /// <summary>
11 /// 设计时支持
12 /// </summary>
13 public class ComboBoxDesigner : ControlDesigner
14 {
15 /// <summary>
16 /// 获取设计时用于表示控件的 HTML
17 /// </summary>
18 /// <returns></returns>
19 public override string GetDesignTimeHtml()
20 {
21 ComboBox comboBox = (ComboBox) base .Component;
22 DropDownList dropDownList = new DropDownList();
23 if (comboBox.Items.Count == 0 && comboBox.Text == string .Empty)
24 {
25 dropDownList.Items.Add( new ListItem( " 未绑定 " ));
26 }
27 else
28 {
29 dropDownList.Items.Add(comboBox.Text);
30 foreach (ListItem item in comboBox.Items)
31 {
32 dropDownList.Items.Add(item);
33 }
34 dropDownList.SelectedIndex = 0 ;
35 }
36 dropDownList.Width = comboBox.Width;
37 StringWriter sw = new StringWriter();
38 HtmlTextWriter tw = new HtmlTextWriter(sw);
39 dropDownList.RenderControl(tw);
40 return sw.ToString();
41 }
42 }
43 }
由于篇幅原因,修改过的htc和项目文件另提供下载