打印

[asp.net教程] asp.net 2.0服务器控件之复合控件事件1

asp.net 2.0服务器控件之复合控件事件1

在上面一篇文章中,我们讨论了有关创建复合控件的基本理论,并且通过一个典型应用掌握了复合控件的呈现方法。本文将继续讲解有关创建复合控件的内容,重点是为复合控件实现事件的具体方法。
   
    复合控件的事件处理简介
   
    谈到自定义控件的事件处理问题,这在前面的系列文章中已经进行讲解。由前文可知,实现控件事件的核心主要是定义事件属性结构和事件处理程序等。然而,这些内容是构建所有自定义服务器控件的基础。仅仅依靠这些方法是无法实现复合控件的事件的。因为,复合控件中包含子控件,这就使得复合控件的事件处理变得复杂起来。显而易见,在复合控件的事件实现过程中,需要面临的最大问题是:由于不允许开发人员直接访问子控件(虽然通过controls集合访问的方法可以实现,但是破坏了程序的封装性,因此是不被允许的),如果子控件的事件不能作为顶级事件引发,那么将无法实现子控件的事件处理。简单的说,即如何实现子控件的事件上传。所谓事件上传是指把子控件的事件暴露为顶级事件,这样父控件可以检查到事件,并按照定义来执行相关事件处理程序。
   
    由以上内容可知,复合控件的事件处理,主要是实现子控件事件上传的过程。下面将介绍两种常用的事件上传实现方法:包含法和冒泡法。这两种方法实现机理不同,然而,完成了同样的功能。在下文中,我们将通过理论结合示例的方法展开讲解。
   
    包含法
   
    包含法的核心是,通过在子控件的事件处理程序中调用复合控件的顶层事件处理程序,以完成子控件的事件上传。在执行过程中,当引发子控件事件后,子控件的事件处理程序将自动调用相关顶层事件处理程序。
   
    包含法的关键步骤如下:
   
    · 在createchildcontrols方法中,为子控件添加事件处理程序。
   
    · 定义顶层事件及其事件处理程序oneventname。
   
    · 在子控件的事件处理程序中调用oneventname。
   
    · 定义事件属性结构。
   
    由以上内容可知,包含法的步骤与前面文章中介绍的实现控件的方法基本类似。关键是多出了一个在createchildcontrols方法中,为子控件添加事件处理程序的步骤。为了读者能够更加清晰的理解包含法,下文列举了一个利用包含法为复合控件实现事件的示例。
   
    首先,利用上一篇文章中介绍的复合控件呈现方法,创建一个由文本框和按钮组成的复合控件,然后,使用上文所述的包含法,将按钮的click事件上传为顶层事件submit。下面列举了该控件的源代码。
   
  using system;
  using system.web.ui;
  using system.web.ui.webcontrols;
  using system.componentmodel;
  using system.componentmodel.design;
  namespace webcontrollibrary{
   public class compositeevent : compositecontrol {
    //声明变量
    private button _button;
    private textbox _textbox;
    private static readonly object eventsubmitkey = new object();
    //定义属性buttontext,用于指定按钮上的文字
    [
     bindable(true), category("appearance"), defaultvalue(""), description("获取或设置显示显示在按钮上的文字")
    ]
    public string buttontext {
     get {
      ensurechildcontrols();
      return _button.text;
     }
     set {
      ensurechildcontrols();
      _button.text = value;
     }
    }
    //定义属性text,表示文本框的输入
   
    [
     bindable(true), category("appearance"), defaultvalue(""), description("获取或设置文本框输入文本")
    ]
    public string text {
     get {
      ensurechildcontrols();
      return _textbox.text;
     }
     set {
      ensurechildcontrols();
      _textbox.text = value;
     }
    }
    // 实现事件属性结构
    public event eventhandler submit {
     add {
      events.addhandler(eventsubmitkey, value);
     }
     remove {
      events.removehandler(eventsubmitkey, value);
     }
    }
    // 实现onsubmit
    protected virtual void onsubmit(eventargs e) {
     eventhandler submithandler = (eventhandler)events[eventsubmitkey];
     if (submithandler != null) {
      submithandler(this, e);
     }
    }
    // 实现submit事件引发的事件处理程序
    private void _button_click(object source, eventargs e) {
     onsubmit(eventargs.empty);
    }
    // 重写icompositecontroldesigneraccessor接口的recreatechildcontrls方法
    protected override void recreatechildcontrols() {
     ensurechildcontrols();
    }
   
    //重写createchildcontrols方法,将子控件添加到复合控件中
   
    protected override void createchildcontrols() {
     controls.clear();
     _button = new button();
     _textbox = new textbox();
     _button.id = "btn";
     _button.click += new eventhandler(_button_click);
     this.controls.add(_button);
     this.controls.add(_textbox);
    }
   
    //重写render方法,呈现控件中其他的html代码
   
    protected override void render(htmltextwriter output) {
     output.addattribute(htmltextwriterattribute.border, "0px");
     output.addattribute(htmltextwriterattribute.cellpadding, "5px");  
     output.addattribute(htmltextwriterattribute.cellspacing, "0px");  
     output.renderbegintag(htmltextwritertag.table);
     output.renderbegintag(htmltextwritertag.tr);   
     output.renderbegintag(htmltextwritertag.td);
     _textbox.rendercontrol(output);
     output.renderendtag();
     output.renderbegintag(htmltextwritertag.td);
     _button.rendercontrol(output);
     output.renderendtag();
     output.renderendtag();
     output.renderendtag();

    }
   }
  }
   
    如上代码所示,复合控件compositeevent中包含两个属性:text和buttontext。前者用于获取或者设置文本框中的文本内容,后者用于获取或者设置按钮的显示文本。另外,复合控件类中还实现了一个submit事件。相关重要逻辑包括:
   
    第一、在重写createchildcontrols方法中,为子控件button添加事件处理程序_button_click。
   
    第二、和普通的自定义事件一样,为复合控件定义一个顶层事件submit。这其中包括定义事件属性结构submit,定义事件处理程序onsubmit。
   
    第三、实现_button_click事件处理程序,调用顶层事件submit的事件处理程序onsubmit。

TOP

返回顶部
AYBlue

Processed in 0.052696 second(s), 7 queries.

当前时区 GMT+8, 现在时间是 2009-1-10 11:58 京ICP备06054220号

清除 Cookies - 联系我们 - 163K.com - Archiver - WAP