zoukankan      html  css  js  c++  java
  • C# event from:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html#a4

    4.3 事件的使用方式

    事件能通过+=和-=两个方式注册或者注销对其处理的方法,使用+=与-=操作符的时候,系统会自动调用对应的 add_XXX、remove_XXX 进行处理。
    值得留意,在PersonManager类的Execute方法中,如果 MyEvent 绑定的处理方法不为空,即可使用MyEvent(string)引发事件。但如果在外界的 main 方法中直接使用 personManager.MyEvent (string) 来引发事件,系统将引发错误报告。这正是因为事件具备了良好的封装性,使外界不能超越事件所在的对象访问其变量成员。

    注意在事件所处的对象之外,事件只能出现在+=,-=的左方。

     此时,开发人员无须手动添加 add_XXX、remove_XXX 的方法,就可实现与4.1例子中的相同功能,实现了良好的封装。

    复制代码
     1     public delegate void MyDelegate(string name);
    2
    3 public class PersonManager
    4 {
    5 public event MyDelegate MyEvent;
    6
    7 //执行事件
    8 public void Execute(string name)
    9 {
    10 if (MyEvent != null)
    11 MyEvent(name);
    12 }
    13 }
    14
    15 class Program
    16 {
    17 static void Main(string[] args)
    18 {
    19 PersonManager personManager = new PersonManager();
    20 //绑定事件处理方法
    21 personManager.MyEvent += new MyDelegate(GetName);
    22 personManager.Execute("Leslie");
    23 Console.ReadKey();
    24 }
    25
    26 public static void GetName(string name)
    27 {
    28 Console.WriteLine("My name is " + name);
    29 }
    30 }
    复制代码

    4.4 事件处理方法的绑定

    在绑定事件处理方法的时候,事件出现在+=、-= 操作符的左边,对应的委托对象出现在+=、-= 操作符的右边。对应以上例子,事件提供了更简单的绑定方式,只需要在+=、-= 操作符的右方写上方法名称,系统就能自动辩认。

    复制代码
     1     public delegate void MyDelegate(string name);
    2
    3 public class PersonManager
    4 {
    5 public event MyDelegate MyEvent;
    6 .........
    7 }
    8
    9 class Program
    10 {
    11 static void Main(string[] args)
    12 {
    13 PersonManager personManager = new PersonManager();
    14 //绑定事件处理方法
    15 personManager.MyEvent += GetName;
    16 .............
    17 }
    18
    19 public static void GetName(string name)
    20 {.........}
    21 }
    复制代码

    如果觉得编写 GetName 方法过于麻烦,你还可以使用匿名方法绑定事件的处理。

    复制代码
     1     public delegate void MyDelegate(string name);
    2
    3 public class PersonManager
    4 {
    5 public event MyDelegate MyEvent;
    6
    7 //执行事件
    8 public void Execute(string name)
    9 {
    10 if (MyEvent != null)
    11 MyEvent(name);
    12 }
    13
    14 static void Main(string[] args)
    15 {
    16 PersonManager personManager = new PersonManager();
    17 //使用匿名方法绑定事件的处理
    18 personManager.MyEvent += delegate(string name){
    19 Console.WriteLine("My name is "+name);
    20 };
    21 personManager.Execute("Leslie");
    22 Console.ReadKey();
    23 }
    24 }
    复制代码

    4.5 C#控件中的事件

    在C#控件中存在多个的事件,像Click、TextChanged、SelectIndexChanged 等等,很多都是通过 EventHandler 委托绑定事件的处理方法的,EventHandler 可说是C#控件中最常见的委托 。

    public delegate void EventHandler (Object sender, EventArgs e)

    EventHandler 委托并无返回值,sender 代表引发事件的控件对象,e 代表由该事件生成的数据 。在ASP.NET中可以直接通过btn.Click+=new EventHandler(btn_onclick) 的方式为控件绑定处理方法。

    复制代码
     1 <html xmlns="http://www.w3.org/1999/xhtml">
    2 <head runat="server">
    3 <title></title>
    4 <script type="text/C#" runat="server">
    5 protected void Page_Load(object sender, EventArgs e)
    6 {
    7 btn.Click += new EventHandler(btn_onclick);
    8 }
    9
    10 public void btn_onclick(object obj, EventArgs e)
    11 {
    12 Button btn = (Button)obj;
    13 Response.Write(btn.Text);
    14 }
    15 </script>
    16 </head>
    17 <body>
    18 <form id="form1" runat="server">
    19 <div>
    20 <asp:Button ID="btn" runat="server" Text="Button"/>
    21 </div>
    22 </form>
    23 </body>
    24 </html>
    复制代码

    更多时候,只需要在页面使用 OnClick=“btn_onclick" 方法,在编译的时候系统就会自动对事件处理方法进行绑定。

    复制代码
     1 <html xmlns="http://www.w3.org/1999/xhtml">
    2 <head runat="server">
    3 <title></title>
    4 <script type="text/C#" runat="server">
    5 public void btn_onclick(object obj, EventArgs e)
    6 {
    7 Button btn = (Button)obj;
    8 Response.Write(btn.Text);
    9 }
    10 </script>
    11 </head>
    12 <body>
    13 <form id="form1" runat="server">
    14 <div>
    15 <asp:Button ID="btn" runat="server" Text="Button" OnClick="btn_onclick"/>
    16 </div>
    17 </form>
    18 </body>
    19 </html>
    复制代码

    EventHandler 只是 EventHandler<TEventArgs> 泛型委托的一个简单例子。事实上,大家可以利用 EventHandler<TEventArgs> 构造出所需要的委托。

    public delegate void EventHandler<TEventArgs> (Object sender, TEventArgs e)

    在EventHandler<TEventArgs>中,sender代表事件源,e 代表派生自EventArgs类的事件参数。开发人员可以建立派生自EventArgs的类,从中加入需要使用到的事件参数,然后建立 EventHandler<TEventArgs> 委托。

    下面的例子中,先建立一个派生自EventArgs的类MyEventArgs作为事件参数,然后在EventManager中建立事件myEvent , 通过 Execute 方法可以激发事件。最后在测试中绑定 myEvent 的处理方法 ShowMessage,在ShowMessage显示myEventArgs 的事件参数 Message。

    复制代码
     1     public class MyEventArgs : EventArgs
    2 {
    3 private string args;
    4
    5 public MyEventArgs(string message)
    6 {
    7 args = message;
    8 }
    9
    10 public string Message
    11 {
    12 get { return args; }
    13 set { args = value; }
    14 }
    15 }
    16
    17 public class EventManager
    18 {
    19 public event EventHandler<MyEventArgs> myEvent;
    20
    21 public void Execute(string message)
    22 {
    23 if (myEvent != null)
    24 myEvent(this, new MyEventArgs(message));
    25 }
    26 }
    27
    28 class Program
    29 {
    30 static void Main(string[] args)
    31 {
    32 EventManager eventManager = new EventManager();
    33 eventManager.myEvent += new EventHandler<MyEventArgs>(ShowMessage);
    34 eventManager.Execute("How are you!");
    35 Console.ReadKey();
    36 }
    37
    38 public static void ShowMessage(object obj,MyEventArgs e)
    39 {
    40 Console.WriteLine(e.Message);
    41 }
    42 }
    复制代码

    运行结果

    4.6 为用户控件建立事件

    在ASP.NET开发中,页面往往会出现很多类似的控件与代码,开发人员可以通过用户控件来避免重复的代码。但往往同一个用户控件,在不同的页面中需要有不同的响应。此时为用户控件建立事件,便可轻松地解决此问题。
    下面例子中,在用户控件 MyControl 中建立存在一个GridView控件,GridView 控件通过 GetPersonList 方法获取数据源。在用户控件中还定义了 RowCommand 事件,在 GridView 的 GridView_RowCommand 方法中激发此事件。这样,在页面使用此控件时,开发人员就可以定义不同的方法处理 RowCommand 事件。

    复制代码
     1 public class Person
    2 {
    3 public int ID
    4 { get; set; }
    5 public string Name
    6 { get; set; }
    7 public int Age
    8 { get; set; }
    9 }
    10
    11 <!-- 用户控件 -->
    12 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="MyControl" %>
    13 <script type="text/C#" runat="server">
    14 protected void Page_Load(object sender, EventArgs e)
    15 {
    16 GridView1.DataSource = GetPersonList();
    17 GridView1.DataBind();
    18 }
    19
    20 //绑定数据源
    21 protected IList<Person> GetPersonList()
    22 {
    23 IList<Person> list = new List<Person>();
    24 Person person1 = new Person();
    25 person1.ID = 1;
    26 person1.Name = "Leslie";
    27 person1.Age = 29;
    28 list.Add(person1);
    29 ...........
    30 return list;
    31 }
    32
    33 public event GridViewCommandEventHandler RowCommand;
    34
    35 protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    36 {
    37 if (RowCommand != null)
    38 RowCommand(sender, e);
    39 }
    40 </script>
    41 <div>
    42 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    43 onrowcommand="GridView1_RowCommand">
    44 <Columns>
    45 <asp:BoundField DataField="ID" HeaderText="ID"/>
    46 <asp:BoundField DataField="Name" HeaderText="Name"/>
    47 <asp:BoundField DataField="Age" HeaderText="Age"/>
    48 <asp:ButtonField CommandName="Get" Text="Select"/>
    49 </Columns>
    50 </asp:GridView>
    51 </div>
    52
    53 <!-- 页面代码 -->
    54 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
    55 <%@ Register Src="~/MyControl.ascx" TagPrefix="ascx" TagName="myControl" %>
    56 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    57
    58 <html xmlns="http://www.w3.org/1999/xhtml">
    59 <head runat="server">
    60 <title></title>
    61 <script type="text/C#" runat="server">
    62 protected void myControl_RowCommand(object sender, GridViewCommandEventArgs e)
    63 {
    64 if (e.CommandName == "Get")
    65 {
    66 GridView gridView=(GridView)sender;
    67 int index = int.Parse(e.CommandArgument.ToString());
    68 label.Text=gridView.Rows[index].Cells[1].Text;
    69 }
    70 }
    71 </script>
    72 </head>
    73 <body>
    74 <form id="form1" runat="server">
    75 <div>
    76 <ascx:myControl ID="myControl" runat="server" OnRowCommand="myControl_RowCommand"></ascx:myControl>
    77 <br />
    78 Select Name : <asp:Label ID="label" runat="server"></asp:Label><br />
    79 </div>
    80 </form>
    81 </body>
    82 </html>
    复制代码

    运行结果

    使用控件已有的事件固然简单,但它限制了传送的参数类型,使开发人员无法传送额外的自定义参数。在结构比较复杂的用户控件中,使用已有的控件事件,显然不够方便,此时,您可以考虑为用户控件建立自定义事件。
    首先用户控件中包含订单信息与订单明细列表,首先定义一个事件参数 MyEventArgs,里面包含了订单信息与一个 OrderItem 数组。然后建立用户控件的委托MyDelegate 与对应的事件 MyEvent,在 Button 的 Click 事件中激发 MyEvent 自定义事件。这样在页面处理方法 myControl_Click 中就可以通过事件参数 MyEventArgs 获取用户控件中的属性,计算订单的总体价格。

    复制代码
      1 <!--   基础类    -->
    2 public class OrderItem
    3 {
    4 public OrderItem(string id,string goods,double price,int count)
    5 {
    6 this.OrderItemID = id; //明细单ID
    7 this.Goods = goods; //商品名称
    8 this.Price = price; //商品单价
    9 this.Count = count; //商品数量
    10 }
    11
    12 public string OrderItemID
    13 { get; set; }
    14 public string Goods
    15 { get; set; }
    16 public double Price
    17 { get; set; }
    18 public int Count
    19 { get; set; }
    20 }
    21
    22 /// 事件参数
    23 public class MyEventArgs:EventArgs
    24 {
    25 public MyEventArgs(string name,string address,string tel,
    26 string orderCode,IList<OrderItem> orderItemList)
    27 {
    28 Name = name; //买家姓名
    29 Address = address; //买家地址
    30 Tel = tel; //买家电话
    31 OrderCode = orderCode; //订单号码
    32 OrderItemList = orderItemList; //订单明细
    33 }
    34
    35 public string Name
    36 { get;set; }
    37 public string Address
    38 { get; set; }
    39 public string Tel
    40 { get; set; }
    41 public string OrderCode
    42 { get; set; }
    43 public IList<OrderItem> OrderItemList
    44 { get; set; }
    45 }
    46
    47 <!-- 用户控件 -->
    48 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="MyControl" %>
    49 <script type="text/C#" runat="server">
    50 protected void Page_Load(object sender, EventArgs e)
    51 {
    52 GridView1.DataSource = GetList();
    53 GridView1.DataBind();
    54 }
    55
    56 //模拟数据源
    57 protected IList<OrderItem> GetList()
    58 {
    59 IList<OrderItem> list = new List<OrderItem>();
    60 OrderItem orderItem = new OrderItem("1", "Asus N75S", 8800, 2);
    61 list.Add(orderItem);
    62 ..........
    63 return list;
    64 }
    65
    66 //自定义委托
    67 public delegate void MyDelegate(object sender,MyEventArgs myEventArgs);
    68 //自定义事件
    69 public event MyDelegate MyEvent;
    70
    71 //按下Button时激发自定义事件
    72 protected void btn_click(object sender, EventArgs e)
    73 {
    74 if (MyEvent != null)
    75 {
    76 MyEventArgs myEventArgs = new MyEventArgs(labelName.Text, labelAddress.Text, labelTel.Text
    77 , labelOrderCode.Text, GetList());
    78 MyEvent(this,myEventArgs);
    79 }
    80 }
    81 </script>
    82 <div>
    83 Name : <asp:Label ID="labelName" runat="server">Leslie</asp:Label><br />
    84 Address : <asp:Label ID="labelAddress" runat="server">ZhongShan University 2A 501</asp:Label><br />
    85 Tel : <asp:Label ID="labelTel" runat="server">13660123456</asp:Label><br />
    86 Order Code : <asp:Label ID="labelOrderCode" runat="server">A12012031223B0030</asp:Label><br /><br />
    87 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="5">
    88 <Columns>
    89 <asp:BoundField DataField="OrderItemID" HeaderText="ID"/>
    90 <asp:BoundField DataField="Goods" HeaderText="Goods"/>
    91 <asp:BoundField DataField="Price" HeaderText="Price"/>
    92 <asp:BoundField DataField="Count" HeaderText="Count"/>
    93 </Columns>
    94 </asp:GridView>
    95 <br />
    96 <asp:Button ID="btn" runat="server" Text="Account" OnClick="btn_click"/>
    97 </div>
    98
    99 <!-- 页面处理 -->
    100 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
    101 <%@ Register Src="~/MyControl.ascx" TagPrefix="ascx" TagName="myControl" %>
    102 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    103
    104 <html xmlns="http://www.w3.org/1999/xhtml">
    105 <head runat="server">
    106 <title></title>
    107 <script type="text/C#" runat="server">
    108 //在页面定义用户控件MyEvent事件的处理方法
    109 protected void myControl_Click(object sender,MyEventArgs e)
    110 {
    111 //计算订单总体价格
    112 double totalPrice=0;
    113 IList<OrderItem> list=e.OrderItemList;
    114 foreach(OrderItem item in list)
    115 totalPrice+=item.Price*item.Count;
    116 //展示订单号及总体费用
    117 labelOrderCode.Text = e.OrderCode;
    118 labelTotalPrice.Text = totalPrice.ToString();
    119 }
    120 </script>
    121 </head>
    122 <body>
    123 <form id="form1" runat="server">
    124 <div>
    125 <ascx:myControl ID="myControl" runat="server" OnMyEvent="myControl_Click"></ascx:myControl>
    126 <br />
    127 OrderCode : <asp:Label ID="labelOrderCode" runat="server"></asp:Label><br />
    128 TotalPrice : <asp:Label ID="labelTotalPrice" runat="server"></asp:Label>
    129 </div>
    130 </form>
    131 </body>
    132 </html>
    复制代码

    运行结果

  • 相关阅读:
    刘墉写给女儿的忠告
    HTML & CSS 小总结
    [LeetCode] 151. Reverse Words in a String 翻转字符串中的单词
    [LeetCode] 340. Longest Substring with At Most K Distinct Characters 最多有K个不同字符的最长子串
    [LeetCode] 127. Word Ladder 单词阶梯
    [LeetCode] 300. Longest Increasing Subsequence 最长递增子序列
    [LeetCode] 354. Russian Doll Envelopes 俄罗斯套娃信封
    [LeetCode] 218. The Skyline Problem 天际线问题
    [LeetCode] 407. Trapping Rain Water II 收集雨水 II
    [LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期
  • 原文地址:https://www.cnblogs.com/songtzu/p/2630326.html
Copyright © 2011-2022 走看看