看了不少有关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和项目文件另提供下载