zoukankan      html  css  js  c++  java
  • 封装控件 学习(2)——C#

    前篇文章简单介绍了如何封装Html来创建我们的ASP.NET服务器控件。这篇说说如何继承ASP.NET独有的WebControl类来制作标准服务器控件。

    先来介绍下WebControl类

    WebControl类:

    WebControl 类从 Control 派生,用作定义 System.Web. UI.WebControls 命名空间中的所有控件的公共方法、属性和事件的基类。提供所有 Web 服务器控件的公共属性、方法和事件。通过设置在此类中定义的属性,可以控制 Web 服务器控件的外观和行为。主要的属性有:AccessKey、Attributes、 Width、Height等。此外,一个从 WebControl 派生的控件也自行参与到 ASP.NET 的主题功能。WebControl类的属性和方法详细的内容可以参看 MSDN

    这里再简单的说下WebControl和HtmlContrlol的区别:

    Web控件和Html控件虽然好多功能相同并且长得很像,但是它们的内部实现 机制是完全不一样的。

    Web控件具有回送功能,能够用ViewState维持控件的状态。Html控件则不能,当点击页面的操作,其状态就会丢失。(ViewState后面会有讲解)

    Html控件与Web控件最大的区别是它们对事件处理的方法不同。对于Html窗体控件,当引发一个事件时,浏览器会处理它。但对于Web控件,事件仅由浏览器生成,但浏览器不会处理它,客户端要给服务器发个信息,告诉服务器处理事件。 不过有些事件,
    比如:按下键/移动/鼠标等事件,Asp.net中没有这些事件(因为这些事件即时性强,服务器处理得不够及时),这时候Html控件就发挥其作用了,结合Html事件协助完成。

    有的资料上说:Web控件要比Html控件执行效率要好。这个没有太好的依据,仅供大家参考,高手也可以谈谈自己的想法。

    自己动手:

    这里我们不像上篇文章那样,简单的创建一个类库工程,而是直接创建ASP.NET服务器控件项目。

    VS2008会自动的为我们生成如下代码:

     
    namespace SelfServerControl
     
    {
     
        [DefaultProperty("Text")]
     
        [ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")]
     
        public class MyControl : WebControl
     
        {
     
            [Bindable(true)]
     
            [Category("Appearance")]
     
            [DefaultValue("")]
     
            [Localizable(true)]
     
            public string Text
     
            {
     
                get
     
                {
     
                    String s = (String)ViewState["Text"];
     
                    return ((s == null) ? "[" + this.ID + "]" : s);
     
                }
     
     
     
                set
     
                {
     
                    ViewState["Text"] = value;
     
                }
     
            }
     
     
     
            protected override void RenderContents(HtmlTextWriter output)
     
            {
     
                output.Write(Text);
     
            }
     
        }
     
    }

    代码说明:

    是不是有点熟悉,很像上节课继承自Control类生成ASP.NET服务器控件的代码。

    代码中定义了一个 Text 属性(属性的声明和上篇基本一样),并使用视图状态(ViewState )存储该属性值。使用视图状态保存回发间的 Text 值。每次回发时,将重新创建页并从视图状态还原值。如果 Text 值并未存储在视图状态中,则在每次回发时会将值设置为其默认的 Empty。ViewState 属性继承自 WebControl,是保存数据值的字典。通过使用 String 键,可输入和检索值。代码中将“Text”用作键。字典中的项被类型化为 Object,然后必须将其强制转换为属性类型。

    ViewState想必大家都已经很熟悉了,简单的理解:当aspx页面重新加载后,为了避免上一次的存放在变量中的数据丢失,用ViewState来保存。

    RenderContents 方法:

    通常,在从 WebControl 派生控件并呈现单个元素时,应重写 RenderContents 方法(而不是 Render 方法),以呈现控件标记中的内容。在呈现控件及其样式属性的开始标记之后,WebControl 的 Render 方法将调用 RenderContents。如果重写 Render 方法以写入内容,则控件将丢失生成到 WebControl 的 Render 方法中的样式呈现逻辑。

    如果我们将上篇的代码复制到这里,也能得到同样的效果。这里就不做演示了。

    WebControl类为开发人员提供了几个特殊的方法,来完成我们对标注服务器控件的开发:

    AddAttributesToRender(HtmlTextWriter.writer):WebControl的子类应该重写该方法,以便包含用于呈现最外层HTML元素的HTML属性的代码块
    RenderBeginTag(HtmlTextWriter writer):WebControl的子类应该重写该方法,以便包含用于呈现最外层HTML元素的打开标记的代码块
    RenderContents(HtmlTextWriter writer): WebControl的子类应该重写该方法,以便包含用于呈现最外层HTML元素的打开和关闭标记之间嵌套的HTML的代码块。
    RenderEndTag(HtmlTextWriter writer):WebControl的子类应该重写该方法,以便包含用于呈现最外层HTML元素的关闭标记的代码块

    实现WebControl类的Render方法:

     
    protected internal override void Render(HtmlTextWriter writer)
     
     
     
    {
     
     
     
      RenderBeginTag(writer);
     
     
     
      RenderContents(writer);
     
     
     
      RenderEndTag(writer);
     
     
     
    }

    AddAttributesToRender方法中发生了什么。该方法将在RenderBeginTag方法中被调用。

    具体的实例在这里就不做了,给大家一个参看的例子。

    简单应用:

    ASP.NET给我们提供了很多现成的控件,比如Label,button,textbox等等。在平时的开发中,我们完全可以不继承Webcontrol类,直接继承它下面控件的子类,这样更有助于我们项目中的应用和开发。下面说个以前在项目中用到的小实例。

     
    namespace MyTextBox
     
    {
     
        [DefaultProperty("Text"), ToolboxData("<{0}:BrianTextBox runat=server></{0}:BrianTextBox>"), Designer("System.Web.UI.Design.WebControls.PreviewControlDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
     
        public class BrianTextBox : System.Web.UI.WebControls.TextBox
     
        {
     
            /// <summary>
     
            /// 构造函数
     
            /// </summary>
     
            public BrianTextBox()
     
                : base()
     
            {
     
                base.Attributes.Add("onfocus", "this.className='" + onFocus + "';");
     
                base.Attributes.Add("onblur", "this.className='" + onBlurCss + "';");
     
                base.CssClass = Class;
     
            }
     
     
     
            private string _onFocusCss = "colorfocus";
     
            [Bindable(true), Category("Appearance"), Description("文本框获取焦点时触发")]
     
            /// <summary>
     
            /// 获取焦点时样式
     
            /// </summary>
     
            public string onFocus
     
            {
     
                get { return _onFocusCss; }
     
                set { _onFocusCss = value; }
     
            }
     
     
     
            private string _onBlurCss = "colorblur";
     
            [Bindable(true), Category("Appearance"), Description("文本框失去焦点时触发")]
     
            /// <summary>
     
            /// 失去焦点时样式
     
            /// </summary>
     
            public string onBlurCss
     
            {
     
                get { return _onBlurCss; }
     
                set { _onBlurCss = value; }
     
            }
     
     
     
            private string _Class = "colorblur";
     
            [Bindable(true), Category("Appearance"), DefaultValue("")]
     
            /// <summary>
     
            /// 样式
     
            /// </summary>
     
            public string Class
     
            {
     
                get { return _Class; }
     
                set { _Class = value; }
     
            }
     
     
     
            /// <summary>
     
            /// 获取焦点的控件ID(如提交按钮等)
     
            /// </summary>
     
            [Bindable(true), Category("Appearance"), DefaultValue("")]
     
            public string SetFocusButtonID
     
            {
     
                get
     
                {
     
                    object o = ViewState[this.ClientID + "_SetFocusButtonID"];
     
                    return (o == null) ? "" : o.ToString();
     
                }
     
                set
     
                {
     
                    ViewState[this.ClientID + "_SetFocusButtonID"] = value;
     
                    if (value != "")
     
                    {
     
                        this.Attributes.Add("onkeydown", "if(event.keyCode==13){document.getElementById('" + value + "').focus();}");
     
                    }
     
                }
     
            }
     
        }
     
    }

    代码不是很难,简单说下。这里我不是继承自WebControl类,而是继承自它的子类TextBox类,向父类中添加了两个属性,分别代表失去焦点时的样式和获取焦点时的样式。还有一个属性是获取焦点的控件ID。这里默认的设定了css的类名称,所以在使用时,需要创建两个css:

     
    <style>
     
        .colorblur
     
        {
     
            cursor:hand;
     
            background-color:Aquamarine;
     
            }
     
           
     
           
     
            .colorfocus
     
        {
     
            cursor:hand;
     
            background-color:Red;
     
            }
     
        </style>

    不用做其他的任何设置,运行,会看到当我们得Textbox获得焦点的时候背景色红色,失去焦点时,背景是蓝色。,当然,这里只是做个例子,获得和失去焦点的样式大家可以自己去设计。

    这只是简单的小应用,给大家提个思路。大家完全可以开动自己创新思维,创造出自己独特的服务器控件。灵活的运用在我们得项目开发中。

  • 相关阅读:
    (转) Linux下Setuid命令!
    Linux SWAP 交换分区配置说明(转)
    linux中ctime,mtime,atime的区别
    无法访问win8默认共享(如C$)解决办法
    Daemon进程
    autofs文件自动挂载系统
    Selinux相关
    解读linux中用户密码规则及忘记root口令的破解(思路)
    windows共享连接显示无法打开
    DOS口令启用停用的管理员密码
  • 原文地址:https://www.cnblogs.com/eve612/p/14278341.html
Copyright © 2011-2022 走看看