zoukankan      html  css  js  c++  java
  • 从简单做起ASP.NET复合控件(修定版)

    从简单做起---ASP.NET复合控件

     

    在你的网页应用程序里面添加用户控件,真的很简单。事实上,你只是做了网页的一部分,添加HTML,然后在应用程序里面使用。尽管用着很简单,但是不方便在应用程序间共享。有一种控件复合性控件,做起来很复杂,但是用着很方便,它可以很方便地在不同的应用程序之间多次使用。这里我们就简单介绍这种控件的生成方法。

     

    我们可以使用MS内置控件,如Textbox等来组建你的复合控件,当然,也可以用自己定义Layout。在这里我们放三个Textbox,让用户来输入日期,当然还有一些逻辑代码来合并这些日期成为一个完整的日期格式。

     

    在这个DEMO中你要建两个工程,一个是复合控件工程Web Control Library,一个是引用这个复合控件的WEB程序。在这里,我们的前者工程叫做,DateEditBox,完成后,会有一个DateEditBox的类。以下这个类的主要信息:

     

     

    namespace MyControls
    {
       [DefaultProperty(
    "Value")]
       [ToolboxData(
    "<{0}:DateEditBox runat=server></{0}:DateEditBox>")]
       
    public class DateEditBox : CompositeControl
       
    {
          
    private TextBox txtMonth = new TextBox();
          
    private TextBox txtDay   = new TextBox();
          
    private TextBox txtYear  = new TextBox();

          
    protected override void OnInit(EventArgs e)
          
    {
             
    base.OnInit(e);
             txtMonth.ID        
    = this.ID + "_month";
             txtMonth.MaxLength 
    = 2;
             txtMonth.Width     
    = this.Width;

             txtDay.ID        
    = this.ID + "_day";
             txtDay.MaxLength 
    = 2;
             txtDay.Width     
    = this.Width;

             txtYear.ID        
    = this.ID + "_year";
             txtYear.MaxLength 
    = 4;
             txtYear.Width     
    = this.Width;
          }


          [Bindable(
    true)]
          [Category(
    "Appearance")]
          [DefaultValue(
    "")]
          [Localizable(
    true)]
          
    public DateTime Value
          
    {
             
    get
             
    {
                EnsureChildControls();
                
    if (txtMonth.Text == "" || txtDay.Text == "" ||
                    txtYear.Text 
    == "")
                   
    return DateTime.MinValue;
                
    else
                   
    return new DateTime(Convert.ToInt32(txtYear.Text),
                      Convert.ToInt32(txtMonth.Text),
                      Convert.ToInt32(txtDay.Text));
             }


             
    set
             
    {
                EnsureChildControls();
                txtMonth.Text 
    = value.Month.ToString();
                txtDay.Text   
    = value.Day.ToString();
                txtYear.Text  
    = value.Year.ToString();
             }

          }

          
    protected override void CreateChildControls()
          
    {
             
    this.Controls.Add(txtMonth);
             
    this.Controls.Add(txtDay);
             
    this.Controls.Add(txtYear);
             
    base.CreateChildControls();
          }

          
    public override void RenderControl(HtmlTextWriter writer)
          
    {
             writer.RenderBeginTag(HtmlTextWriterTag.Table);
             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtMonth.RenderControl(writer);
             writer.RenderEndTag();    
    // td
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             writer.Write(
    "/");
             writer.RenderEndTag();    
    // td
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtDay.RenderControl(writer);
             writer.RenderEndTag();    
    // td
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             writer.Write(
    "/");
             writer.RenderEndTag();    
    // td
             writer.RenderBeginTag(HtmlTextWriterTag.Td);
             txtYear.RenderControl(writer);
             writer.RenderEndTag();    
    // td
             writer.RenderEndTag();    // tr
             writer.RenderEndTag();    // table
          }

       }

    }


     

     

    这个类有点复杂,让我们来分析一下。我个内是以一些属性定义开始的。第一个是默认值,用来指定值的属性。第二个是用来指定本控件可以用在WEB页面的,一般是从VS工具箱拖拉到页面上的。你也注意到了,这个类是继承至CompositeControl,,这个内是专为自定义复合控件定制的。关于这个类的详细信息可以查看MSDN

     

    OnInit事件里,我们给这三个子控件设置一些默认值,如ID,宽度,字长等。我们设置ID以复控件ID开头,是因为在后面我们将用这些ID来查找这些控件。

     

    我们有值属性设置器,就可以很方便的设置和读取它们各自的值,当然,在这里,你完全可以加入一些基本的验证。在这里就不说这些了。接下来就是CreateChildControls方法和RenderControl方法。前者可以让页面在回传的时候保存控件状态。如果没有这方法,你的子控件就不能保存视图状态,所以也不能正常显示在回传页面的时候。后一个方法负责让你的控件在页面上正常显示。这样的话,你的控件就会显示以下格式:

    table
       tr
          td [txtMonth] /td
          td [/] /td
          td [txtDay] /td
          td [/] /td
          td [txtYear] /td
       /tr
    /table

     

    当然在HtmlTextWriter里面你也可以自己定义你的样式,排版等。如果你想在其它工程中引用这个控件的话,首先要编译,成功后会在BIN里面出现*.dll,引用这个DLL在新的工程里面,然后,在你的页面代码里加入如下代码:

     

    <%@ Register Assambly=”myControls” Namespace=”myControls” TagPrefix=”MC” %>

     

    一旦在工程里添加DLL引用后,工程会自动COPY这个DLL到BIN目录里面,在你的VS智能感知里面会出现类如MC:DateEditBox,在后台代码里面,你可以看到控件的属性值。

     

    总结:

    你还可以添加更多的功能在这个控件里,但是这里只是显示最基本的控件需要代码。创建新的子控件,设置它们的ID值,添加到控件集合里,最后呈现出来。至此一个复合控件就完成了。之后,在添加更多的事件,属性和方法等,让你的控件看起来更酷一些。

    P.S.大家可以注意到在这段代码里面有个EnsureChildControls()方法,在作者的原文中没有相关的说明,非常感谢wangzhe.king在这里提出问题,我想大多数朋友都不太清楚,这个方法,在此说明一下:

    这个方法在检测当前ChildControlsCreated的值,如果是FALSE的话,那么就调用这个方法。ASP.NET调用这个方法,以保证子控件已经构建完毕。在大多数情况下,自定义服务器控件开发者不必重写这个方法。这个方法大多数用在属性器里面,因为在设置或得到属性值以前,你要检测子控件是否已经构建了。

    官方详细解说,点此查看!
    译自:CodeGuru 原文地址

  • 相关阅读:
    form查询相关表
    获取datagrid更新初始值、新值
    数据库约束查询
    强名称工具(来着.NET)
    使用IE插件不能打开的解决
    导入导出报错
    List批量任务多线程执行工具类
    在C#中使用NHibernate框架查询数据
    使用bat文件顺序执行多个应用程序
    用C#实现抽象工厂模式
  • 原文地址:https://www.cnblogs.com/lgp/p/537007.html
Copyright © 2011-2022 走看看