自定义控件--基础2

Control类程序按控件的步骤:

呈现控件的步骤

1.RenderControl方法

代码如下:

protected void RenderControl(HtmlTextWriter writer)

{

if(Visible)

{

Render(writer);
}

}

先判断Visible,然后进行Render.

2.Render方法

public virtual void Render(HtmlTextWriter writer)

{

RenderChildren(writer);

}

使用HtmlTextWriter将标记字符和文本输出,然后调用RenderChildren方法.

3.RenderChildren方法

public virtual void RenderChildren(HtmlTextWriter writer)

{

for(Control c in Controls)

{

c.RenderControl(writer);

}

}

判断当前控件是否有子控件,然后调用RenderControl方法,根据子控件的visible值输出子控件.

 

下面来看一下控件的事件处理.

1.我们知道Button有一个Click事件,我们打开vs,导航至Button的定义,可以看到如下:

public class Button : WebControl, IButtonControl, IPostBackEventHandler
{
}

其中IPostBackEventHandler接口是负责处理回发事件的.如果自定义空间需要处理回发事件,那么就实现该接口就可以了,我们查看该接口:

    // 摘要:
    //     定义 ASP.NET 服务器控件为处理回发事件而必须实现的方法。
    public interface IPostBackEventHandler
    {
        // 摘要:
        //     当由类实现时,使服务器控件能够处理将窗体发送到服务器时引发的事件。
        //
        // 参数:
        //   eventArgument:
        //     表示要传递到事件处理程序的可选事件参数的 System.String。
        void RaisePostBackEvent(string eventArgument);
    }

在该接口的RaisePostBackEvent方法中,有一个参数,该参数表示的是要传递给处理程序的参数.

处理回发事件的步骤如下:

1.自定义服务器控件类必须实现IPostBackEventHandler接口,并实现该接口成员RaisePostBackEvent方法

2.为表单定义UniqueID,以与IPostBackEventHandler服务器控件的UniqueID相对应.

注意:只有为引起回传的控件的name属性分配了UniqueID,才能够正确实现捕获回传事件。

 例子如下:

    public class Btn : Control,IPostBackEventHandler
    {
        public event EventHandler click;

        public void RaisePostBackEvent(string eventArgument)
        {
            if (click != null)
            {
                click(this, EventArgs.Empty);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("<input type='submit' name='" + this.UniqueID + "' value='click me!'/>");
        }
    }

页面调用:

    <cc1:Btn ID="Btn1" runat="server" onclick="Btn1_click">
    </cc1:Btn>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

    protected void Btn1_click(object sender, EventArgs e)
    {
        Label1.Text = "点击事件!";
    }
注意:
EventArgs.Empty表示没有事件数据的事件,而不是表示空事件!
此时,如果控件中存在多个时间,编译器将会为每一个事件委托生成一个字段,这样的效率是比较低的,可以采用另一种方式来对事件处理进行优化:
我们可以使用EventHandlerList,该类有几个重要的方法,具体如下:
        public void AddHandler(object key, Delegate value);
        public void AddHandlers(EventHandlerList listToAddFrom);
        public void RemoveHandler(object key, Delegate value);
示例:
    public class Btn : Control, IPostBackEventHandler
    {
        private static readonly object EventDBClick = new object();

        public event EventHandler DBClick
        {
            add
            {
                Events.AddHandler(EventDBClick, value);
            }
            remove
            {
                Events.RemoveHandler(EventDBClick, value);
            }
        }
        
        public void RaisePostBackEvent(string eventArgument)
        {
            OnDBClick(EventArgs.Empty);
        }

        protected virtual void OnDBClick(EventArgs e)
        {
            EventHandler handler = (EventHandler)Events[EventDBClick];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("<input type='submit' name='" + this.UniqueID + "' value='click me!'/>");
        }
    }
posted @ 2009-12-23 21:56  Localhost  阅读(258)  评论(0编辑  收藏  举报