欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET图像界面按钮的clicked事件浅谈

程序员文章站 2024-03-02 12:09:22
    但是事件并不局限于图像界面,也可能是满足程序的某个逻辑判断触发了事件。引发事件的对象叫做事件发送方,捕获事件并对其做出响应的...

    但是事件并不局限于图像界面,也可能是满足程序的某个逻辑判断触发了事件。引发事件的对象叫做事件发送方,捕获事件并对其做出响应的对象叫做事件接收方。但是事件发送方并不知道哪个对象或者方法会处理它引发的事件,所以需要在事件发送方和事件接收方之间存在一媒介,明确某个对象或者某个类型的某个方法会对这个事件进行响应。.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);
        }
    }