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

 更新时间:2013年04月17日 10:54:40   投稿:shangke  
在.NET图像界面开发中最常见的一个事件大概就是按钮的clicked事件了,当点击图形界面的按钮时,就会调用一个与这个事件相关的方法对这个事件进行响应,做一些相关操作。

发送方的对象为了给事件接收对象传递一些额外信息,就需要写一个派生于System.EventArgs的类,封装一些数据。

复制代码 代码如下:

    public class DrawEventArgs:EventArgs
    {
        privatedouble m_Size;
        public DrawEventArgs(doublesize)
        {
            m_Size = size;
        }
        public double Size
        {
            get
            {
                returnm_Size;
            }
        }
    }

    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);
        }
    }

相关文章

  • asp.net如何得到GRIDVIEW中某行某列值的方法

    asp.net如何得到GRIDVIEW中某行某列值的方法

    这篇文章介绍了获得GRIDVIEW中某行某列值的方法具体步骤,有需要的朋友可以参考一下
    2013-07-07
  • asp.net+ajax的Post请求实例

    asp.net+ajax的Post请求实例

    这篇文章主要介绍了asp.net+ajax的Post请求实现方法,实例分析了Ajax的发送post数据的原理与技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • Asp.net内置对象之Request对象(概述及应用)

    Asp.net内置对象之Request对象(概述及应用)

    Request对象主要用于获取来自客户端的数据,如用户填入表单的数据、保存在客户端的Cookie等,本文将围绕Request对象,讲解其的主要作用:读取窗体变量、读取查询字符串变量、取得Web服务器端的系统信息。取得客户端浏览器信息等等,感兴趣的朋友可以了解下
    2013-02-02
  • OpenCms 带分页的新闻列表

    OpenCms 带分页的新闻列表

    有一些网友在新闻列表分页上还遇到一些问题,正好这个blog上也忘记了此部分内容,现在补充上,功能是实现了,可以自己再做些优化,OpenCms7.0.5下测试通过,内容如下(编辑器的插入代码功能有问题,就直接把代码粘上了
    2008-07-07
  • Element NavMenu导航菜单的使用方法

    Element NavMenu导航菜单的使用方法

    这篇文章主要介绍了Element NavMenu导航菜单的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • aspx如果引用cs中的变量的方法

    aspx如果引用cs中的变量的方法

    引用cs中变量的实现方法
    2008-07-07
  • Visual Studio 2017正式版发布 亮点看这里

    Visual Studio 2017正式版发布 亮点看这里

    终于等到你,最强 IDE Visual Studio 2017 正式版发布,这篇文章主要为大家详细解析了Visual Studio 2017正式版发布的细节,亮点看这里
    2017-03-03
  •  ASP.NET Core 模型验证过滤器的两种实现方法

     ASP.NET Core 模型验证过滤器的两种实现方法

     在.Net Core的时代中,框架会帮你自动验证,本文主要介绍了 ASP.NET Core 模型验证过滤器的两种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • RabbitMQ .NET消息队列使用详解

    RabbitMQ .NET消息队列使用详解

    这篇文章主要为大家详细介绍了RabbitMQ .NET消息队列使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • asp.net显示自己的网页图标的几种方式

    asp.net显示自己的网页图标的几种方式

    多tab的浏览器,你一定会发现tab前边的个性图标,关于这个东西有好几种做法,下面与大家分享下
    2014-05-05

最新评论