zoukankan      html  css  js  c++  java
  • Asp.net控件开发学习笔记(九)服务器控件事件

    EventCollection

    如果在单个控件中有多个事件,那么使用System.ComponentModel.EventHandlerList对事件进行保存将会在内存占用上有不错的提高。EventHandlerList对一个类内发布多个事件提供了一个列表容器。下面是多个事件和使用EventHandlerList的对比示意:


     
    第一步是实例化一个EventHandlerList的实例:

    protected EventHandlerList eventList = new EventHandlerList();

    第二步是声明一个容器用于保存事件的key

    private static readonly object ClickEvent = new object();

    最后一步是像往常一样声明一个事件,但有所不同的是就像属性的get和set程序块一样,对于事件C#提供了add和remove关键字:

    public event EventHandler Click

            {

                add

                {

                    Events.AddHandler(ClickEvent, value);

                }

                remove

                {

                    Events.RemoveHandler(ClickEvent, value);

                }

          }

     而在这时的事件调用方法就会像下面代码:

    protected virtual void OnClick(EventArgs e)

            {

                EventHandler clickEventDelegate = (EventHandler)Events[ClickEvent];

                if (clickEventDelegate != null)

                 {

                    clickEventDelegate(this, e);

                }

         }

     上面代码首先从事件列表中通过索引器以第一步中保存事件的key为参数提取出事件并检查客户端是否注册到此事件,如果是,则激发事件。

     

    Command事件和事件冒泡

        Command事件是System.Web.UI.WebControls命名空间里的强大模式。这个最好的例子是GridView


       

     在GridView的Row里嵌套的button点击会触发Command事件,后台可以根据CommandArgument的不同来决定是执行edit操作还是delete操作等。而事件冒泡有些像javascript里的事件冒泡,但有所不同的是这里的事件冒泡到能够处理这个事件的地方停止,比如上图中command事件会冒泡到DataGrid里的ItemCommand里停止,因为ItemCommand事件可以对command事件进行处理.

     在定义Command事件时会和前面大同小异,不同之处在于首先需要一个继承与System.EventArgs的CommandEventArgs类来进行参数传递,代码如下

    public class CommandEventArgs : EventArgs

    {

        public CommandEventArgs(string _commandName,string _commandArgument)

    {

        CommandName=_commandName;

        CommandArgument=_commandArgument;

    }

           private string commandname;

            private string commandArgument;

            public virtual string CommandName

            {

                get

                {

                    return commandname;

                }

                set

                {

                    commandname = value;

                }

            }

            public virtual string CommandArgument

            {

                get

                {

                    return commandArgument;

                }

                set

                {

                    commandArgument = value;

                }

            }   

    }

    然后在需要定义的控件里定义这两个属性,代码如下:

             public virtual string CommandName

             {

                get

                {

                    object name = ViewState["CommandName"];

                    if (name == null)

                        return string.Empty;

                    else

                        return (string)name;

                }

                set

                {

                    ViewState["CommandName"] = value;

                }

            }

            public virtual string CommandArgument

            {

                get

                {

                    object arg = ViewState["CommandArgument"];

                    if (arg == null)

                        return string.Empty;

                    else

                        return (string)arg;

                }

                set

                {

                    ViewState["CommandArgument"] = value;

                }

            }

    然后重复前面的步骤,在控件内部定义命令事件:

    private static readonly object CommandKey = new object();

            public event CommandEventHandler Command

            {

                add

                {

                    Events.AddHandler(CommandKey, value);

                }

                remove

                {

                    Events.RemoveHandler(CommandKey, value);

                }

            }

    最后一步和前面说的引发事件的OnXXX的实现都略有不同,这里在控件内部实现的代码如下:

           protected virtual void OnCommand(CommandEventArgs ce)

            {

                CommandEventHandler commandEventDelegate =(CommandEventHandler)Events[CommandKey];

                if (commandEventDelegate != null)

                {

                    commandEventDelegate(this, ce);

                }

                RaiseBubbleEvent(this, ce);

            }

     注意最后一句,RaiseBubbleEvent方法.这个方法可以将控件的事件传递到它的父容器上。

     到这里很多人都会好奇,那CommandName和CommandArgument两个参数是如何传入到CommandEventArgs里去的呢?

     其实是在引发事件时传入的,代码如下:

      OnCommand(new CommandEventArgs(CommandName, CommandArgument));

     

    DEMO 带Command事件的Button

        其实这个Demo就是把上面的代码全部拼装起来,代码可能会有点长,代码如下:

        namespace DemoButton

    {

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

        public class ButtonDemo : Control, IPostBackEventHandler

        {

            public delegate void CommandEventHandler(object sender,CommandEventArgs e);

            public virtual string Text

            {

                get

                {

                    object text = ViewState["Text"];

                    if (text == null)

                        return string.Empty;

                    else

                        return (string)text;

                }

                set

                {

                    ViewState["Text"] = value;

                }

            }

            private static readonly object ClickKey = new object();

            public event EventHandler Click

            {

                add

                {

                    Events.AddHandler(ClickKey, value);

                }

                remove

                {

                    Events.RemoveHandler(ClickKey, value);

                }

            }

            protected virtual void OnClick(EventArgs e)

            {

                EventHandler clickEventDelegate = (EventHandler)Events[ClickKey];

                if (clickEventDelegate != null)

                {

                    clickEventDelegate(this, e);

                }

            }

            private static readonly object CommandKey = new object();

            public event CommandEventHandler Command

            {

                add

                {

                    Events.AddHandler(CommandKey, value);

                }

                remove

                {

                    Events.RemoveHandler(CommandKey, value);

                }

            }

            public virtual string CommandName

            {

                get

                {

                    object name = ViewState["CommandName"];

                    if (name == null)

                        return string.Empty;

                    else

                        return (string)name;

                }

                set

                {

                    ViewState["CommandName"] = value;

                }

            }

            public virtual string CommandArgument

            {

                get

                {

                    object arg = ViewState["CommandArgument"];

                    if (arg == null)

                        return string.Empty;

                    else

                        return (string)arg;

                }

                set

                {

                    ViewState["CommandArgument"] = value;

                }

            }

            protected virtual void OnCommand(CommandEventArgs ce)

            {

                CommandEventHandler commandEventDelegate = (CommandEventHandler)Events[CommandKey];

                if (commandEventDelegate != null)

                {

                    commandEventDelegate(this, ce);

                }

                RaiseBubbleEvent(this, ce);

            }

            public void RaisePostBackEvent(string argument)

            {

                OnCommand(new CommandEventArgs(CommandName, CommandArgument));

                //OnClick(EventArgs.Empty);

            }

            protected override void Render(HtmlTextWriter writer)

            {

                base.Render(writer);

                Page.VerifyRenderingInServerForm(this);

                writer.Write("<INPUT type=""submit""");

                writer.Write(" name=""" + this.UniqueID + """");

                writer.Write(" id=""" + this.UniqueID + """");

                writer.Write(" value=""" + Text + """");

                writer.Write(" />");

            }

        }

     

        public class CommandEventArgs : EventArgs

        {

            public CommandEventArgs(string _commandName, string _commandArgument)

            {

                CommandName = _commandName;

                CommandArgument = _commandArgument;

            }

            private string commandname;

            private string commandArgument;

            public virtual string CommandName

            {

                get

                {

                    return commandname;

                }

                set

                {

                    commandname = value;

                }

            }

            public virtual string CommandArgument

            {

                get

                {

                    return commandArgument;

                }

                set

                {

                    commandArgument = value;

                }

            }

        }

    }

    前台代码:

    首先注册页面控件:

     <%@ Register Namespace="DemoButton" TagPrefix="cc" %>

    前台代码:

       <cc:ButtonDemo runat="server" Text="第一个按钮" ID="bt1" CommandName="bt1"

            CommandArgument="第一个button的参数" oncommand="bt1_Command" ></cc:ButtonDemo>

          

     <cc:ButtonDemo runat="server" Text="第二个按钮" ID="bt2" CommandName="bt1"

            CommandArgument="第二个button的参数" oncommand="bt1_Command" ></cc:ButtonDemo>

    事件处理程序:

        protected void bt1_Command(object sender, DemoButton.CommandEventArgs e)

        {

            if (e.CommandName == "bt1")

            {

                Response.Write("第一个button被点击了,参数是"+e.CommandArgument);

            }

            else if (e.CommandArgument == "bt12")

            {

                Response.Write("第二个button被点击了,参数是" + e.CommandArgument);

            }

    }

     

    Demo的结果很简单,就不演示了:-)

  • 相关阅读:
    Git官方推荐用书
    二叉树-补习
    POJ 2251 Dungeon Master(三维BFS)
    Codeforces 675C Money Transfers (思维题)
    HDU 1195 Open the Lock(BFS)
    HDU 1010 Tempter of the Bone(DFS+剪枝)
    POJ 1426 Find The Multiple(DFS,BFS)
    POJ 3216 Prime Path (BFS)
    POJ 3278 Catch that cow(BFS)
    UVa 572 Oil Deposits(简单DFS)
  • 原文地址:https://www.cnblogs.com/CareySon/p/1582906.html
Copyright © 2011-2022 走看看