C# 关于事件的一些心得

使用事件

定义和发布事件

事件是建立在委托的基础上的,当某类发生某一事情后,可以通过事件机制通知已经注册的类或对象正在发生的事情,然后这些类或对象做出响应。

事件的本质是委托,但它通常是特定的函数类型,可以将事件理解为委托变量,订阅事件就是为委托变量赋值,同样也是使用“+=”/“-=”。

在定义事件之前要先定义委托,只不过这个委托是特定的函数类型,它没有返回值,并且具有两个参数sender和arg。

例如:

Public delegate void PriceChangedEventHandler(object sender,PriceChangedEventAgrs arg);

为什么会这样呢?这是因为在.Net 框架中,事件是基于EventHandler委托和EventArgs基类的。

在看上面的例子中的两个参数,一个是object类型的sender,表示事件的发起者,一个是PriceChangedEventArgs 类型的arg,表示事件参数,通常是由EventArgs类派生出来的,所以,在定义一个事件之前,通常先定义一个参数类,派生自EventArgs,该类包含了事件发起者需要传递给事件订阅者的全部信息。

定义好委托之后,需要定义一个事件,可以理解为定义一个委托变量,只不过不是直接定义,需要加上“event”关键字,来说明这是一个事件,不过可以理解为就是一个委托变量。

例如:

Public event PricechangedEventHandler PriceChanged;

接下来就是引发事件,可以理解为使用委托变量,引发事件通常放在一个名为OnXXXX()的函数中,这样在在其他地方调用该函数时,就引发事件,即使用委托变量,调用相应的函数(事件处理程序)。

订阅和处理事件

订阅,实际上就是将函数添加到委托变量的函数列表中,在这里,就是将事件处理程序添加到事件的列表中。

处理事件,就是委托变量调用的函数,即事件发生后调用事件处理程序。

例子

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace EventApp

{

class Program

{

/// <summary>

/// 实现用户订阅事件,也就是为委托变量赋值,通过+=。。。

/// </summary>

/// <param name="args"></param>

static void Main(string[] args)

{

//定义两个shop对象,用来引发事件

Shop shop1 = new Shop("Shop1");

Shop shop2 = new Shop("Shop2");

//定义两个customer对象,用来订阅事件并处理事件

Customer cust1 = new Customer("Customer1");

Customer cust2 = new Customer("Customer2");

//cust1订阅shop1的pricechanged事件

shop1.PriceChanged += cust1.Shop_PriceChanged;

//引发事件

Console.WriteLine("1. shop1.UpdatePrice(\"Goods1\",2.2f)......");

shop1.UpdatePrice("Goods1", 2.2f);

//cust2订阅shop2的pricechanged事件

shop2.PriceChanged += cust2.Shop_PriceChanged;

//引发事件

Console.WriteLine("2. shop2.UpdatePrice(\"Goods2\",3.4f),......");

shop2.UpdatePrice("Goods2", 3.4f);

//cust2订阅shop1的pricechanged事件

shop1.PriceChanged += cust2.Shop_PriceChanged;

//引发事件

Console.WriteLine("3. shop1.UpdatePrice(\"Goods3\",55.2f)......");

shop1.UpdatePrice("Goods3", 55.2f);

//cust1取消shop1的pricechanged事件

shop1.PriceChanged -= cust1.Shop_PriceChanged;

//引发事件

Console.WriteLine("4. shop1.UpdatePrice(\"Goods4\",9.2f)......");

shop1.UpdatePrice("Goods4", 9.2f);

Console.ReadLine();

}

/// <summary>

/// 商品价格变化发生时的事件参数

/// </summary>

public class PriceChangedEventArgs:EventArgs

{

private string str_Name;

public string Str_Name

{

get { return this.str_Name; }

}

private float flo_Price;

public float Flo_Price

{

get { return this.flo_Price; }

}

public PriceChangedEventArgs(string name,float newprice)

{

this.str_Name = name;

this.flo_Price = newprice;

}

}

/// <summary>

/// 定义委托

/// </summary>

/// <param name="sender"></param>

/// <param name="arg"></param>

public delegate void PriceChangedEventHandler(object sender, PriceChangedEventArgs arg);

public class Shop

{

private string shopname;

/// <summary>

/// 属性

/// </summary>

public string ShopName

{

get { return this.shopname; }

}

/// <summary>

/// 构造函数

/// </summary>

/// <param name="spname"></param>

public Shop(string spname)

{

this.shopname = spname;

}

public event PriceChangedEventHandler PriceChanged;       //相当于声明委托变量,这里通过event关键字将其称为事件

/// <summary>

/// 引发事件的函数

/// </summary>

/// <param name="arg"></param>

protected void OnPriceChanged(PriceChangedEventArgs arg)

{

if (this.PriceChanged!=null)

{

PriceChanged(this, arg);                      //相当于使用委托变量,这里只不过将使用委托变量放在了一个函数里,整体成为引发事件,实质就是使用委托变量。

}

}

public void UpdatePrice(string nm,float nprice)

{

PriceChangedEventArgs arg = new PriceChangedEventArgs(nm, nprice);

this.OnPriceChanged(arg);

}

}

/// <summary>

/// 客户信息,订阅事件

/// </summary>

public class Customer

{

private string name;

public string _Name

{

get { return this.name; }

}

public Customer(string nm)

{

this.name = nm;

}

/// <summary>

/// PriceChanged事件处理函数

/// </summary>

/// <param name="sender"></param>

/// <param name="arg"></param>

public void Shop_PriceChanged(object sender, PriceChangedEventArgs arg)

{

Shop sp = sender as Shop;

if (sp != null)

{

Console.WriteLine("{0}收到{1}:{2}新价格为{3}¥", this._Name, sp.ShopName, arg.Str_Name, arg.Flo_Price);

}

}

}

}

}

时间: 2024-08-26 19:52:35

C# 关于事件的一些心得的相关文章

android 事件传递机制 心得

看了网上很多资料. 最后我发现可以用很简单的几句话就能把它说清楚 1 每个 viewgroup 内都有 三个方法 a dispatchTouchEvent 是自己决定要不要(管他爹)要这个苹果的 一般使用方法是 在此方法内 getParent().requestDisallowInterceptTouchEvent(false/true) true表示要了, 苹果拿到手 false 表示 不要了,那这个苹果还在他爹那里 b onintercepTouchEvent 是这个苹果要不要往下发的,(到

Android开发之PullToRefresh的Click点击事件的监听实现长按删除Item

本文为原创博客,出自http://blog.csdn.net/minimicall 到今天为止,搜芽的卖家版本应该来说已经基本完成,攻坚克难的一路过来.速度也控制的比较好. 项目过程进度 从任务分配量上来看,基本还是我个人英雄主义.接下来这样不行.但暂时也没办法,师弟还需要一个学习的过程.智质不错,而且态度端正.相信搜芽买家,他就可以承担更多的开发任务了. 接下来进入正题,说我们的PullToRefresh的点击事件.其实,我是想做长按进入删除的. 见效果图.当然这个是我做出来之后的了,但做出来

前端心得---仿IOS拾取器控件(转轮控件)

希望做一个类似IOS拾取器的控件,在IOS上该控件的效果是这样的:,我也把该效果称之为为轮子效果. 要实现这个效果,能够用到的技术点非常简单,无非是transform的translate3d和rotate,不过要想很好的实现,还要建立一个精确的数学模型,来解决如何[摆放]的问题.特别是这个效果不是静态的,需要满足鼠标滑动的时,这个轮子要转起来,这就需要仔细思索了.当然,在最开始重点还是要搞清楚自变量是什么.因变量是什么.它们之间的关系是什么以及该需求的一些性质.找到了好的性质,可以减轻工作量,并

Android ListView无法触发ItemClick事件

Android ListView无法触发ItemClick事件 开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点.原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这

MVP实战心得—封装Retrofit2.0+RxAndroid+RxBus

响应式编程框架,rxjava的扩展,很爽的链式编程 魅力在于对数据的处理,与线程切换的灵活性. 用来处理异步操作(Lambda表达式不会用.用Lambda表达式代码会更少,但不会的人会看不懂代码.不是很推荐) RxBus 用RxJava实现的EventBus 说说为什么要配合起来用 Retrofit负责链接网络,请求网络. RxAndroid负责处理请求的结果.异步操作 RxBus可以很方便的进行各组件之间的通信. 我之前是用asynchttpclient做网络请求的,各种代码缩进,if套if,

Gridview, ListView中的item含有checkbox,setOnItemClickListener方法失效的问题

1) 设置CheckBoxandroid:clickable="false"  通过外部View的点击改变其状态. <CheckBox android:id="@+id/select_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/album

android:descendantFocusability用法简析

开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点.原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,

Listview的onItemClickListener无法响应的解决方法(转)

转:http://www.cnblogs.com/androidez/archive/2013/03/08/2950425.html 开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点.原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子

android:descendantFocusability

开发中很常见的一个问题,项目中的GridView不仅仅是简单的文字和图片,常常需要自己定义GridView,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点.原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子