.NET图像界面按钮的clicked事件浅谈
但是事件并不局限于图像界面,也可能是满足程序的某个逻辑判断触发了事件。引发事件的对象叫做事件发送方,捕获事件并对其做出响应的对象叫做事件接收方。但是事件发送方并不知道哪个对象或者方法会处理它引发的事件,所以需要在事件发送方和事件接收方之间存在一媒介,明确某个对象或者某个类型的某个方法会对这个事件进行响应。.net用委托作为事件发送方与事件接收方之间的媒介,委托只有一个签名,只要方法签名与委托签名匹配的方法,都可以声明自己对这个委托类型的事件的感兴趣,接收并处理它。
事件发送方的对象为了给事件接收对象传递一些额外信息,就需要写一个派生于system.eventargs的类,封装一些数据。
public class draweventargs:eventargs
{
privatedouble m_size;
public draweventargs(doublesize)
{
m_size = size;
}
public double size
{
get
{
returnm_size;
}
}
}
下面声明一委托,该委托有两个参数,一个是参数代表事件的发送方,另一个是参数是该事件封装的数据。
public delegate void shapesizechanged(objectsender,draweventargs e);
shapesizechanged的实例可以绑定到任何和它方法签名匹配的方法上。
下面是自定义事件委托,
public event shapesizechanged sizechanged;
下面是一个负责引发事件的类型代码,
public class drawmanager
{
public event shapesizechangedsizechanged;
protectedvoid onsizechanged(draweventargse)
{
shapesizechangedtemp = sizechanged;
//是否有委托与该事件关联
if(temp != null)
{
temp(this,e);
}
}
public void sizechange(doublesize)
{
draweventargse = new draweventargs(size);
onsizechanged(e);
}
}
而后定义两个监听事件的类型,
public class square
{
publicsquare(drawmanager drawmanager)
{
//drawmanager.sizechanged+= drawsquare;
//把事件关联到委托上
drawmanager.sizechanged += new shapesizechanged(drawsquare);
}
public void drawsquare(objectsender, draweventargs e)
{
console.writeline(string.format("thesquare'length = {0}", e.size));
}
public void detach(drawmanagerdrawmanager)
{
//drawmanager.sizechanged-= drawsquare;
//解除事件和委托的关联
drawmanager.sizechanged -= new shapesizechanged(drawsquare);
}
}
public class rectangle
{
publicrectangle(drawmanager drawmanager)
{
drawmanager.sizechanged +=drawrectangle;
}
public void drawrectangle(objectsender, draweventargs e)
{
console.writeline(string.format("therectangle'length={0} and width={1}.",e.size*2,e.size));
}
public void detach(drawmanagerdrawmanager)
{
drawmanager.sizechanged -=drawrectangle;
}
}
测试代码,
class program
{
static void main(string[]args)
{
drawmanagerdrawmanager = new drawmanager();
rectanglerect = new rectangle(drawmanager);
squaresquare = new square(drawmanager);
//引发事件
drawmanager.sizechange(5);
//解除监听事件
square.detach(drawmanager);
drawmanager.sizechange(10);
console.readline();
}
}
/*运行结果
the rectangle'length=10 and width=5.
the square'length = 5
the rectangle'length=20 and width=10.
*/
.net中的事件模式和观察者模式非常相似,也可谓是观察者模式在.net下的进化版吧,下面用观察者模式实现上面功能以做对比,首先定义两个接口,iobserver和iobservable,如下
public interface iobserver
{
voidnotify(draweventargs e);
}
public interface iobservable
{
voidregister(iobserver observer);
voidunregister(iobserver observer);
}
下面是改写后的两个观察者类,
public class newrectangle:iobserver
{
privateobservermanager m;
publicnewrectangle(observermanager omanager)
{
m=omanager;
omanager.register(this);
}
public void notify(draweventargse)
{
console.writeline(string.format("therectangle'length={0} and width={1}.", e.size * 2, e.size));
}
public void detach()
{
m.unregister(this);
}
}
public class newsquare:iobserver
{
privateobservermanager m;
publicnewsquare(observermanager omanager)
{
m=omanager;
omanager.register(this);
}
public void notify(draweventargse)
{
console.writeline(string.format("thesquare'length = {0}.", e.size));
}
public void detach()
{
m.unregister(this);
}
}
下面是负责通知观察者的类型,
public class observermanager:iobservable
{
protectedarraylist arrlist;
publicobservermanager()
{
arrlist = newarraylist();
}
public void register(iobserverobserver)
{
arrlist.add(observer);
}
public void unregister(iobserverobserver)
{
if(arrlist.contains(observer))
{
arrlist.remove(observer);
}
}
public void notifyobservers(doublesize)
{
draweventargse = new draweventargs(size);
foreach(iobserver observer inarrlist)
{
observer.notify(e);
}
}
public void sizechanged(doublesize)
{
notifyobservers(size);
}
}
下面是调用代码,
static void main(string[]args)
{
observermanageromanager = new observermanager();
newrectanglerect = new newrectangle(omanager);
newsquaresquare = new newsquare(omanager);
omanager.sizechanged(5);
square.detach();
omanager.sizechanged(10);
console.readline();
}
最好运行下代码,这样可以更easy的理解这两种模式微妙的差别了。
对事件来说,还可以显式的用add和remove编写事件访问器,事件访问器通常有编译器生成,所以可以显式的用事件访问器修改drawmanager类型,
public class drawmanager
{
privateevent shapesizechangedm_sizechanged;
privatereadonly objectm_lock = new object();
public event shapesizechangedsizechanged
{
add
{
lock(m_lock)
{
m_sizechanged += value;
}
}
remove
{
lock(m_lock)
{
m_sizechanged -= value;
}
}
}
protectedvoid onsizechanged(draweventargse)
{
shapesizechangedtemp = m_sizechanged;
//是否有委托与该事件关联
if(temp != null)
{
temp(this,e);
}
}
public void sizechange(doublesize)
{
draweventargse = new draweventargs(size);
onsizechanged(e);
}
}
上一篇: java结合HADOOP集群文件上传下载
下一篇: Java实现获取前、后N天日期的函数分享