• 从零开始开发服务器控件


    一、控件生命周期:


    简单概述:


    1:初始化(对应Onlnit方法)


    2:加载视图状态(对应LoadViewState方法)


    3:加载回传数据(对应LoadPostData方法)


    4:装载(对应OnLoad方法)


    5:数据回传事件通知(对应RaisePostDataChangedEvent方法)


    6:触发回发事件(对应RaisePostBackEvent方法)


    7:预呈现(对应OnPreRender方法)


    8:保存视图状态(对应SaveViewState方法)


    9:呈现(对应Render方法)


    10:卸载(对应OnUnload方法)


    11:释放(对应Dispose方法)


    简单实例:


    protected override void
    OnInit(EventArgs e)

    {

    OutPut("1.
    OnInit");

    base.OnInit(e);

    this.Page.RegisterRequiresPostBack(this);

    }
      protected override void
    LoadViewState(object savedState)

    {

    OutPut("2.
    LoadViewState");

    base.LoadViewState(savedState);

    }


    public virtual bool
    LoadPostData(string postDataKey, NameValueCollection
    postCollection)

    {

    OutPut("3.
    LoadPostData");

    return true;
    }


    protected override void
    OnLoad(EventArgs e)

    {

    OutPut("4.
    OnLoad");

    base.OnLoad(e);
    }


    public virtual void
    RaisePostDataChangedEvent()

    {

    OutPut("5.
    RaisePostDataChangedEvent");

    }


    public virtual void
    RaisePostBackEvent(string
    eventArgument)

    {

    OutPut("6. RaisePostBackEvent");

    }


    protected override void
    OnPreRender(EventArgs e)

    {

    OutPut("7.
    OnPreRender");

    base.OnPreRender(e);

    }


    protected override object
    SaveViewState()

    {

    OutPut("8.
    SaveViewState");

    base.SaveViewState();

    return new Pair();
    }


    protected override void
    Render(HtmlTextWriter writer)

    {

    writer.Write("<INPUT type=button name="{0}" value="Click Me!"
    style='position:absolute; left: 20; top: 280px' onclick="{1}">",
    this.UniqueID, Page.ClientScript.GetPostBackEventReference(this,
    ""));

    OutPut("9.
    Render");

    base.Render(writer);
    }


    protected override void
    OnUnload(EventArgs e)

    {

    OutPut("10.OnUnload");

    base.OnUnload(e);

    }

    public
    override void Dispose()

    {

    OutPut("11.Dispose");

    base.Dispose();

    }
    private void OutPut(string
    strText)

    {
    if
    (this.DesignMode ==
    false)

    {

    HttpContext.Current.Response.Write(strText +
    "<br>");

    }
    }



    二、控件呈现顺序(以Render开头方法)


    RenderContror(HtmlTextWriter writer)


    Render(HtmlTextWriter writer)


    RenderBeginTag(HtmlTextWriter writer)


    RenderContents(HtmlTextWriter writer)


    RenderEndTag(HtmlTextWriter writer)



    三、Render呈现控件的几种方式


    概述:


    1、使用HtmlTextWriter类输出


    2、直接输出HTML标签


    3、使用服务器控件的HtmlGenericcontrol类方法


    实例:


      protected override void
    RenderContents(HtmlTextWriter
    output)

    {
    //方式1

    output.AddAttribute(HtmlTextWriterAttribute.Href, "http://www.cnblogs.com/");

    output.AddAttribute(HtmlTextWriterAttribute.Target,
    "blank");

    output.AddStyleAttribute(HtmlTextWriterStyle.Color,
    "Blue");

    output.AddStyleAttribute(HtmlTextWriterStyle.Cursor,
    "Hand");

    output.RenderBeginTag(HtmlTextWriterTag.A);

    output.Write(this.Text1);

    output.RenderEndTag();



    output.WriteBreak();



    //方式2

    output.Write("<a href='http://www.csdn.net' target='blank'
    style='color:Blue;cursor:Hand;'>");

    output.Write(this.Text2);

    output.Write("</a>");



    output.Write("<br>");



    //方式3

    HtmlGenericControl A = new
    HtmlGenericControl("A");

    A.Attributes.Add("href", "http://blog.csdn.net/ChengKing");

    A.Attributes.Add("target",
    "blank");

    A.Style.Add(HtmlTextWriterStyle.Color,
    "Blue");

    A.Style.Add(HtmlTextWriterStyle.Cursor,
    "Hand");

    A.InnerText =
    this.Text3;

    A.RenderControl(output);
    }



    四、 开发控件常用方法



    1、AddAttributesToRender方法(为当前自定义控件容器标记增加属性,即对控件呈现HTML标记的最外层一级增加属性)


    例:



    [ToolboxData("<{0}:AddAttributesToRenderControl
    runat=server></{0}:AddAttributesToRenderControl>")]

    public class AddAttributesToRenderControl :
    WebControl
    {

    /// <summary>
    ///
    重载TagKey属性,
    使用<Table>替换掉默认的<Span>

    /// </summary>
    protected
    override HtmlTextWriterTag TagKey

    {

    get

    {

    return
    HtmlTextWriterTag.Table;

    }
    }



    protected override void
    AddAttributesToRender(HtmlTextWriter
    writer)

    {

    writer.AddAttribute(HtmlTextWriterAttribute.Border,
    "0px");

    writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,
    "0px");

    writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing,
    "0px");

    base.AddAttributesToRender(writer);

    }


    protected override void RenderContents(HtmlTextWriter
    output)

    {

    //输出三行内容

    output.RenderBeginTag(HtmlTextWriterTag.Tr);

    output.RenderBeginTag(HtmlTextWriterTag.Td);

    output.Write("<a href='http://www.cnblogs.com' target='blank'
    style='color:Blue;cursor:Hand;'>");

    output.Write("【博客园】【CNBlog】");

    output.Write("</a>");

    output.RenderEndTag();

    output.RenderEndTag();



    output.RenderBeginTag(HtmlTextWriterTag.Tr);

    output.RenderBeginTag(HtmlTextWriterTag.Td);

    output.Write("<a href='http://www.csdn.net' target='blank'
    style='color:Blue;cursor:Hand;'>");

    output.Write("【中国软件开发网】【CSDN】");

    output.Write("</a>");

    output.RenderEndTag();

    output.RenderEndTag();



    output.RenderBeginTag(HtmlTextWriterTag.Tr);

    output.RenderBeginTag(HtmlTextWriterTag.Td);

    output.Write("<a href='http://blog.csdn.net/ChengKing' target='blank'
    style='color:Blue;cursor:Hand;'>");

    output.Write("【金鹰的博客】【ChengKing(ZhengJian)】");

    output.Write("</a>");

    output.RenderEndTag();

    output.RenderEndTag();

    }
    }


    2、CreateChildcontrols方法(一般用于创建组合控件)


    例:


    protected override void CreateChildControls()


    {


    Controls.Clear();


    Button _button = new Button();


    button.ID="btnOK";


    button.CommandName = "ButtonClick";


    this.Controls.Add(_button);



    TextBox textBox = new TextBox();


    textBox.ID="tbText";


    this.Controls.Add(textBox);


    }


    3、EnsureChildControls方法(确定服务控件是否包含子控件,首先调用ChildControlsCreated检查是否包含,如果不包含则调用CreateChildControls方法)


    例:


    this.EnsureChildControls();


    4、RecreateChildControls方法(间接调用CreateChildControls方法。使其在设计模式下,可创建子控件。默认在设计模式下CreateChildControls方法是不执行的)


    例:


    protected virtual void RecreateChildControls()


    {


    if(this.ChildControlsCreated
    == false)


    {



    base.RecreateChildControls();


    }


    }


    5、FindControl、FindControlExtend方法(在复合容器中查找子控件方法)


    public override Control FindControl(string id)


    {


    Control found =
    base.FindControl(id);


    if(found == null)


    {


    found =
    this.Page.FindControl(id);


    }


    if(found == null)


    {


    found =
    this.FindControlExtend(id,this.Controls);


    }


    if(found == null)


    {


    found =
    this.FindControlExtend(id,this.Page.Controls);


    }


    return found;


    }


    private Control FindControlExtend(string id,ControlCollection
    controls)


    {


    int i;


    Control Found = null;


    for (i=0;i<controls.Count;i++)


    {



    if(controls[i].ID == id)


    {



    Found = countrols[i];



    break;


    }



    if(controls[i].Controls.Count > 0)


    {



    Found = FindControlExtend(id,controls[i].Controls);



    if(Found !=null)break;


    }


    }


    return Found;


    }


    五、开发控件常用属性及接口


    1、ChildControlsCreated
    属性(数据类型bool,用于获取一个值,指示是否已创建服务器控件的子控件,功能为了避免CreateChildControls方法重复创建控件)


    例: base.ChildControlsCreated = false; if(
    base.ChildControlsCreated == false)


    2、Controls 属性(数据类型
    ControlCollection,用于获取ControlCollection对象,表示指定服务器控件子控件集合.)


    3、DesignMode 属性(数据类型bool,表示控件的模式分类设计模式与运行模式两种)


    4、INamingContainer接口(是一个没有任何方法的接口,功能创建新的命名范围以保证子控件在控件层次结构树中具有唯一的ID)


    六、常用开发技巧


    1、DesignMode(五节3已讲)、增强FindControl功能(四节5已讲)前面已讲不再敖述。


    2、屏蔽基类控件中的属性


    例:


    [Bindable(false),Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]


    public override Unit Height


    {


    get { return new Unit(); }


    }



    注:Bindable( false)表示不需要绑定;Browsable(false)不在属性窗口显示;EditorBrowsable(EditorBrowsableState.Never)指定不在编辑器中看到,即在后台*.cs
    文件中不会智能提示此属性.


    3、设置控件ID规范


    一般一个控件主要使用以下三个属性作为唯一标志:ID,UniqueID,ClientID.
    其中ID表示我们给他命令的ID;Unique表示服务端ID,ClientID表示客户端ID;


    4、在Rendery方法中利用基类资源


    例:base.Render(writer);


    七、复合控件实例(由一个简单的文本框与正则表达式验证控件组成)


    using System;
    using System.Collections.Generic;
    using
    System.ComponentModel;
    using System.Text;
    using System.Web;
    using
    System.Web.UI;
    using System.Web.UI.WebControls;


    namespace KingControls
    {

    [DefaultProperty("TextBoxValue")]

    [ToolboxData("<{0}:Field
    runat=server></{0}:Field>")]
    public class Field :
    CompositeControl

    {
    private Label
    lb;
    private TextBox
    tb;
    private
    RegularExpressionValidator
    rev;


    [Category("LabelTextBox")]

    [Description("标签显示信息")]
    public
    string LabelTitle

    {

    get

    {

    this.EnsureChildControls();

    return
    this.lb.Text;

    }

    set

    {

    this.EnsureChildControls();

    this.lb.Text =
    value;

    }

    }


    [Category("LabelTextBox")]

    [Description("文本框显示文本")]
    public
    string TextBoxValue

    {

    get

    {

    this.EnsureChildControls();

    return
    tb.Text;

    }

    set

    {

    this.EnsureChildControls();

    tb.Text =
    value;

    }

    }


    [Category("LabelTextBox")]

    [Description("标签宽度")]
    public Unit
    LabelWidth

    {

    get

    {

    this.EnsureChildControls();

    return
    this.lb.Width;

    }

    set

    {

    this.EnsureChildControls();

    this.lb.Width =
    value;

    }

    }


    [Category("LabelTextBox")]

    [Description("标签高度")]
    public Unit
    LabelHeight

    {

    get

    {

    this.EnsureChildControls();

    return
    this.lb.Height;

    }

    set

    {

    this.EnsureChildControls();

    this.lb.Height =
    value;

    }
    }


    private Unit unitTextBoxWidth =
    Unit.Empty;

    [Category("LabelTextBox")]

    [Description("文本框宽度")]
    public Unit
    TextBoxWidth

    {

    get

    {

    this.EnsureChildControls();

    return
    this.tb.Width;

    }

    set

    {

    this.EnsureChildControls();

    this.tb.Width =
    value;

    }
    }


    private Unit unitTextBoxHeight =
    Unit.Empty;

    [Category("LabelTextBox")]

    [Description("文本框宽度")]
    public Unit
    TextBoxHeight

    {

    get

    {

    this.EnsureChildControls();

    return
    this.tb.Height;

    }

    set

    {

    this.EnsureChildControls();

    this.tb.Height =
    value;

    }

    }


    [Category("LabelTextBox")]

    [Description("验证表达式")]
    public
    string ValidateExpression

    {

    get

    {

    this.EnsureChildControls();

    return
    this.rev.ValidationExpression;

    }

    set

    {

    this.EnsureChildControls();

    this.rev.ValidationExpression =
    value;

    }

    }


    [Category("LabelTextBox")]

    [Description("错误提示")]
    public
    string ErrorMessage

    {

    get

    {

    this.EnsureChildControls();

    return
    this.rev.ErrorMessage;

    }

    set

    {

    this.EnsureChildControls();

    this.rev.ErrorMessage =
    value;

    }
    }


    public
    Field()

    {


    }


    ///
    <summary>
    /// 建立子控件实例,
    并设置默认值
    ///
    </summary>
    protected
    override void
    CreateChildControls()

    {

    this.Controls.Clear();


    lb = new
    Label();

    this.lb.ID =
    "lbTitle";

    this.lb.Width =
    Unit.Pixel(50);

    this.Controls.Add(lb);


    tb = new
    TextBox();

    this.tb.ID =
    "tbValue";

    this.tb.Width =
    Unit.Pixel(100);

    this.Controls.Add(tb);




    rev = new
    RegularExpressionValidator();

    this.rev.ID =
    "revValidator";

    this.rev.ControlToValidate =
    this.tb.ID;

    this.rev.ErrorMessage =
    "[输入格式不正确!]";

    this.rev.Display =
    ValidatorDisplay.Static;

    this.Controls.Add(this.rev);



    this.ChildControlsCreated = true;

    }



    protected override void
    RecreateChildControls()

    {
    if
    (this.ChildControlsCreated ==
    false)

    {

    base.RecreateChildControls();
    //强制执行CreateChildControls方法

    }

    }


    protected override void Render(HtmlTextWriter
    writer)

    {

    writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,
    "0");

    writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing,
    "0");

    writer.AddAttribute(HtmlTextWriterAttribute.Border,
    "0");

    writer.RenderBeginTag(HtmlTextWriterTag.Table);



    writer.RenderBeginTag(HtmlTextWriterTag.Tr);



    writer.RenderBeginTag(HtmlTextWriterTag.Td);

    this.lb.RenderControl(writer);

    writer.RenderEndTag();



    writer.RenderBeginTag(HtmlTextWriterTag.Td);

    this.tb.RenderControl(writer);

    writer.RenderEndTag();


    if
    (String.IsNullOrEmpty(this.ValidateExpression) == false &&
    this.DesignMode ==
    false)

    {

    writer.RenderBeginTag(HtmlTextWriterTag.Td);

    this.rev.RenderControl(writer);

    writer.RenderEndTag();

    }



    writer.RenderEndTag();

    writer.RenderEndTag();



    return;

    }


    }
    }

  • 相关阅读:
    linux软件安装方式
    docker 安装 jenkins touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
    [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    Linux 常用命令 服务器间scp 用户 export 创建文件、软连接
    redis 安装 集群 主从 哨兵 docker
    WPF密码框中禁止复制、粘贴
    Application 统计在线人数
    【转义字符】HTML 字符实体&lt; &gt: &amp;等
    SQL语句统计每天的数据
    正则表达式计算代码数
  • 原文地址:https://www.cnblogs.com/chjf2008/p/2088984.html
Copyright © 2020-2023  润新知