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>
复制代码

运行结果

原文地址:https://www.cnblogs.com/songtzu/p/2630326.html