asp.net 创建web自定义控件.
最近因为工作需要写了一个asp.net的web的自定义控件. 总结一下心得.
写控件的过程中, 遇到了几个问题.
1. 资源的引用, 比如说控件中要使用js, 图片什么的, 应该如此去处理.
2. 在写控件的时候, 设置属性的时候, visual studio 总是崩溃, 找了几个小时才找到原因.
3. 就是如何响应外部的postback.
如何创建自定义控件.
如果是visual studio2005的话, 需要创建Visual C# – Windows – Web Control Library 项目.
如果是Visual Studio 2008的话, 是要创建 Visual C# – Web – ASP.NET Server Control 这一个项目.
项目建立好之后, 如果需要在项目中使用JavaScript的话, 则需要继承INamingContainer接口.
然后, 具体继承什么扩展, 是根据你的需要来的, 如果你需要增加Dropdownlist,则继承自Dropdownlist. Textbox, Label等等,同样道理.
我这里需要的是一个组合控件. 即是一个文本框与一个下拉列表的组合. 因此我选择继承自CompositeControl
然后override CreateChildControls的方法, 就可以在里面进行编程了. 不过需要注意的是, 一定要把 base.CreateChildControls(); 这一行给禁用掉, 否则你的控件什么都显示出不来.
如果需要将来在引用控件的时候, 在工具栏上面, 控件左侧显示一个小图票, 可以设置ToolboxBitmap选项.
[ToolboxBitmap(typeof(DropDownList))] public partial class SearchableList : CompositeControl, INamingContainer { protected override void CreateChildControls() {//这里书写控件 Textbox txt = new Textbox(); txt.Text = "Hello CompositeControl"; txt.ID = "txt"; txt.TextChanged += new EventHandler(txt_TextChanged); //后面会用到. txt.AutoPostback = this.TextboxPostBack; this.Controls.Add(txt); //base.CreateChildControls(); //一定要删除,否则控件不会显示内容. } }
当然, 还需要的是定义控件的属性.如果需要控件显示在属性菜单上面. 则需要设置上面的标签.例子如下.
[Bindable(true)] [Category("Appearance")] //哪一个分类里面, 可以自己定义 [DefaultValue("")] //默认的值 [Localizable(true)] //是否本地化. public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } }
这里有几点要注意的.
1. 如果属性的类型是一个自定义类型的话, 该类一定是 [Serializable]
2. 所有的属性的上面都需要定义标签. 最起码也要定义一个[Browsable(false)]或者是[Browsable(true)]
3. 并不是所有的属性都可以设置为[Browsable(true)], 像dropdownlist的selectindex,如果设置了, 在Design的时候, 选中控件, 会导致VS崩溃.
4. 属性一定要放在ViewState里面, 否则的话, 定义的状态不会永久保存, 在postback之后,会消失.
如何响应外部的POSTBACK.
要响应外问的POSTBACK, 首先要注册事件. 然后写根据前面已经注册的事件,来写处理程序.
public event EventHandler TextChanged; protected virtual void textbox_TextChanged(object sender, EventArgs e) { if (TextChanged != null) { TextChanged(this, e); } }
这里需要注意2点.
1. Textbox的Autopostback需要设置为True, 当然, 可以通过属性来设置.
2. 在Web 页面定义事件的时候, 不要把自定义控件的事件注册过程写在if(!Page.IsPostback)里面, 这样会丢失事件. 正在研究更好解决的方法.
[Bindable(true), Category("MyCategory"), Localizable(true), Browsable(true)] public bool TextboxPostBack { set { ViewState["istestpostback"] = value; } get { return ViewState["istestpostback"] == null ? false : (bool)ViewState["istestpostback"]; } }
外部资源的引用.
其实外部资源的引用相对简单
[assembly: WebResource("NameSpaceLibrary.JavaScript.js.js", "text/javascript", PerformSubstitution = true)] namespace NameSpaceLibrary { //然后调用的时候,使用 this.Page.ClientScript.RegisterClientScriptResource(this.GetType(), "NameSpaceLibrary.JavaScript.js.js"); }
这里很简单.NameSpaceLibrary命名空间, JavaScript是文件夹, js.js是文件名. 可以根据自己的情况更改.
这里需要注意的是, 在创建好了文件之后,如js文件, 右击js文件, 属性, 一定要选择Build Action: Embedded Resource , 编译进dll里面. 这样在调用的时候, 就不用额外的把js文件复制给别人了~
小站呼隆隆来访,博主本该热烈欢迎,哈哈,无奈博主不在,小站留个脚印方便下次再来。。。。
o(∩_∩)o