自定义控件--基础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!'/>");

        }

    }

你可能感兴趣的:(自定义控件)