学习c#(第9天):理解c#中的事件(一种见解)

表的内容 目录介绍路线图我们的话题调查。net Windows应用程序按钮单击事件(案例研究)幕后publisher-subscriber模型弄脏你的手:创建自定义事件代码解释结论 介绍 事件的核心和重要概念之一c#编程环境和坦白地说有时很难理解他们没有适当的解释和例子。 所以我想写这篇文章的方便学习者和初学者。 图片来源:http://d.wildapricot.net/images/newsblog/bigstock - 19983578. jpg?sfvrsn=0事件 路线图 让我们再次修改我们的路线图, 潜水在OOP(第一天):多态和继承(早期绑定/编译时多态)潜水在OOP(第二天):多态和继承(继承)潜水OOP(第三天):多态和继承(动态绑定/运行时多态)潜水在OOP(第四天):多态和继承(关于Abstarct类在c#中)潜水在OOP(第五天):都是用c#访问修饰符(公共/私人/保护/内部/密封/常量/只读的字段)学习c#(6天):理解枚举在c#中(一个实际的方法)学习c#(7天):用c#属性(一个实际的方法)学习c#(8天):用c#索引器(一个实际的方法)学习c#(9天):了解c#事件(Insight)学习c#(第十天):代表在c#中(一个实际的方法)学习c#(11天):c#事件(一个实际的方法) 我们的话题 一个事件在一个非常简单的语言是一个行动或事件,如点击按键,鼠标移动,或系统生成的通知。应用程序可以响应事件时发生。事件消息发送的对象来表示事件的发生。事件是一个有效的进程间通信。他们对一个对象是有用的,因为它们提供信号状态改变,这可能是对象的有价值的客户。 如果上面的句子很难理解我们把这个简单的如果在形式被用户点击一个按钮会触发一个事件,如果一个用户类型文本框键被按下,因此会触发一个事件等等。 从MSDN的解释, ”事件在c#中是一个类的方式向客户提供通知类的一些有趣的事情发生在一个对象。最熟悉的用于在图形用户界面事件;一般来说,表示控件的类接口的事件通知当用户做了一些控制(例如,单击一个按钮)。 事件,然而,不需要只用于图形化界面。事件通常提供一个有用的信号状态更改为对象,对象的客户可能是有用的。事件是一个重要的构建块创建类,可以在大量不同的程序中重用。 使用代表事件的声明。如果您尚未研究代表教程,在继续之前你应该这样做。回想一下,一个委托对象封装一个方法,以便它可以被称为匿名。一个事件是一个类的方法让客户给它代表的方法应该被称为当事件发生时。当事件发生时,委托(s)给它的客户调用。” 下图是广义表示解释事件和事件处理。 在c#中,代表们使用事件来实现事件处理。. net框架绑定事件模型使用代表通知被称为事件处理程序与方法。生成事件时,委托调用关联的事件处理程序。 调查。net Windows应用程序按钮单击事件(案例研究) 打开你的visual studio和创建一个windows应用程序。你会得到一个名为Form1.cs的形式在你的windows应用程序项目。添加一个简单的按钮,表单,就拖拽。在属性面板的按钮,绑定按钮的单击事件与事件代码,点击显示一些文本。您可以浏览附件源代码的理解。 现在当你运行应用程序时,表单将显示只有一个按钮,单击该按钮,看看会发生什么, 我们可以看到表单上的按钮被点击的用户,因此按钮单击事件被解雇,是由委托反过来叫button_click方法(事件处理程序方法)显示消息框。 在上面示例事件声明,事件处理程序委托声明,声明所有由。net我们只需要编写代码处理事件在这种情况下,代码来显示消息框。 在窗帘后面 如果我们调查Form1.Designer.cs和遵循以下步骤如图我们可以很容易地发现事件的关键字和委托关键词,从而找出它们的定义。 因为我们还没有看到定义的语法可能看起来陌生但我们会但是现在不久就遵循的步骤图。 步骤1:打开Form1.Designer.Cs解决方案资源管理器 步骤2:在Form1.Designer.Cs单击事件和事件委托。 第三步:双击this.button1。单击并按F12查看点击事件定义,同样双击系统。EventHandler并按F12看到EventHandler委托定义。 事件的定义, 委托的定义, Publisher-Subscriber模型 事件在一个类声明长大并与事件处理程序相关联的使用代表在同一类或其他类。事件是一个类的一部分,同样的类是用于发布事件。然而,其他类可以接受这些事件或换句话说可以订阅这些事件。使用事件发布者和订阅者模型。 , 一个出版商的定义是一个对象,其中包含事件和委托。协会委托的事件也是出版商中指定的类。出版商类的对象调用事件,通知到其他对象。 用户是一个对象,想接受事件并提供一个事件处理程序。委托的出版商用户类的类调用方法。这种方法在用户类是事件处理程序。发布者和订阅者模型实现可以由相同的类定义。 代表在c#中发挥非常重要的作用,它是一个实体可以直接放到一个类的名称空间。这个质量委托就可以访问所有其他类。代表工作面向对象模式,试图遵循由封闭方法和对象封装在一起。用c#委托System.Delegate定义一个类,并使用名称空间。代表理想的匿名方法调用。我将更详细地讨论事件和代表在我即将到来的文章。 下图显示了使用的机制出版商和用户对象。 让你的手脏:创建自定义事件 让我们把我们的手脏通过构建我们自己的事件处理的例子。在下面的例子中我们将看到如何定义定制的事件以及如何提高,如何处理我们自己的定制的事件处理器。 在我们的简单示例中,我们将构建一个控制台应用程序的银行,在一个事件TransactionMade提高每当客户事务和响应通知发送给他。 现在让我们做一些严肃的编码。 首先我们定义类账户。 我们可以添加一个构造函数来初始化变量int BalanceAmount我们班上将帐户余额。 隐藏,复制Code

public int BalanceAmount;
 public Account(int amount)
 {
     BalanceAmount = amount;
 }

然后我们定义事件和委托。 事件发布者类的定义(Account类)包括委托宣言以及基于委托事件的声明。下面的代码定义一个委托名叫TransactionHandler TransactionMade事件,调用TransactionHandler委托时提出: 隐藏,复制Code

 public delegate void TransactionHandler(object sender,TransactionEventArgs e);
public event TransactionHandler TransactionMade;

如你所见,我们委托的名称是TransactionHandler,其签名包含一个void返回值和对象和TransactionEventArgs类型的两个参数。如果您想要实例化这个委托地方,函数作为构造函数传递参数应该有相同的签名这个委托。 引发事件时我们通过一些数据来源于用户在一个类。例如,在我们的示例中我们想提供事务数量和类型的事务。所以我们定义了一个类TransactionEventArgs将继承的EventArgs传递数据用户类。我们已经宣布两个私有变量一个int _transactionAmount通过交易数量和其他信息字符串_transactionType事务类型(信用卡/借记卡)信息传递给用户类。 这是类定义: 隐藏,复制Code

public class TransactionEventArgs : EventArgs
  {
      public int TranactionAmount { get; set; }
      public string TranactionType { get; set; }

      public TransactionEventArgs(int amt, string type)
      {
          TranactionAmount = amt;
          TranactionType = type;
      }
  }

现在,一切都在我们的帐户类。现在我们将定义我们的通知方法将调用信用或借记卡交易,提高我们的事件。 在借方方法平衡数量将扣除和事件将提高通知用户平衡数量改变了,同样的信贷余额方法将会认为和通知将被发送到用户类。 付款方法 隐藏,复制Code

public void Debit(int debitAmount)
       {
           if (debitAmount < BalanceAmount)
           {
               BalanceAmount = BalanceAmount - debitAmount;
               TransactionEventArgs e = new TransactionEventArgs(debitAmount,"Debited");
               OnTransactionMade(e); // Debit transaction made
           }
       }

信贷的方法 隐藏,复制Code

public void Credit(int creditAmount)
   {

       BalanceAmount = BalanceAmount + creditAmount;
       TransactionEventArgs e = new TransactionEventArgs(creditAmount,"Credited");
        OnTransactionMade(e); // Credit transaction made

   }

正如你所看到的在上述方法我们已经创建了实例TransactionEventArgs我们通过实例OnTransactionMade()方法,并称之为。你一定在想什么OnTransactionMade()是在这里做的这是我们的方法提高我们的事件。这是它的定义: 隐藏,复制Code

protected virtual void OnTransactionMade(TransactionEventArgs e)
   {
       if (TransactionMade != null)
       {
           TransactionMade(this, e); // Raise the event
       }
   }

下面是我们的账户类的完整代码: 隐藏,收缩,复制Code

namespace EventExample
{
 public delegate void TransactionHandler(object sender,TransactionEventArgs e); // Delegate Definition
    class Account
    {
        public event TransactionHandler TransactionMade; // Event Definition

        public int BalanceAmount;

       public Account(int amount)
        {
            this.BalanceAmount = amount;
 
        }

        public void Debit(int debitAmount)
        {
            if (debitAmount < BalanceAmount)
            {
                BalanceAmount = BalanceAmount - debitAmount;
                TransactionEventArgs e = new TransactionEventArgs(debitAmount,"Debited");
                OnTransactionMade(e); // Debit transaction made
            }
        }

        public void Credit(int creditAmount)
        {

            BalanceAmount = BalanceAmount + creditAmount;
            TransactionEventArgs e = new TransactionEventArgs(creditAmount,"Credited");
             OnTransactionMade(e); // Credit transaction made
            
        }

        protected virtual void OnTransactionMade(TransactionEventArgs e)
        {
            if (TransactionMade != null)
            {
                TransactionMade(this, e); // Raise the event 
            }
        }
    }

提高一个事件是通过调用事件TransactionMade (e),; 这个事件将由我们的事件处理器处理。 现在让我们定义订阅者类,它将对事件作出反应,并通过自己的方法相应地处理事件。 首先创建一个名为TestMyEvent的类并定义一个方法SendNotification,它的返回类型和参数应该与之前在publisher类中声明的委托相匹配。基本上,这个方法会在我们的余额发生变化时做出反应,并通知用户(通过在控制台写这个)。 下面是定义: 隐藏,复制Code

private static void SendNotification(object sender, TransactionEventArgs e)
    {
        Console.WriteLine("Your Account is {0} for Rs.{1} ", e.TranactionType, e.TranactionAmount);
     }

现在在订阅者类的Main()方法中创建实例并传递一些初始余额。然后,将事件处理程序的引用传递给事件,并将在该事件响应上调用的方法传递给事件处理程序。 隐藏,复制Code

private static void Main()
       {
           Account MyAccount = new Account(10000);
           MyAccount.TransactionMade += new TransactionHandler(SendNotification);
           MyAccount.Credit(500);
           Console.WriteLine("Your Current Balance is : " + MyAccount.BalanceAmount);
           Console.ReadLine();


       }

因此,下面是订阅者类(TestMyEvent)的完整定义: 隐藏,复制Code

class TestMyEvent
    {
        
        private static void SendNotification(object sender, TransactionEventArgs e)
        {
      Console.WriteLine("Your Account is {0} for Rs.{1} ", e.TranactionType, e.TranactionAmount);
 
        }

        private static void Main()
        {
            Account MyAccount = new Account(10000);
            MyAccount.TransactionMade += new TransactionHandler(SendNotification);
            MyAccount.Credit(500);
            Console.WriteLine("Your Current Balance is : " + MyAccount.BalanceAmount);
            Console.ReadLine();

        }
    }

我们的输出将是: 代码的解释 在我们的示例中我们的帐户类是通知的出版商账户余额的变化如果借方或贷方可以看到从代码我们提出了事件在借方/贷方方法如果事件被提升到一定高度,然后有人采取行动所以TestMyEvent类是用户类的借方/贷方交易因此帐户余额的变化因此它被通知从出版商类和它的工作取决于它和处理事件通过调用事件处理程序方法SendNotification。因此,很明显,事件可以在一个类(Publisher)中定义,几个订阅者类可以根据自己的需要对其进行操作。 结论 我们研究了。net事件,构建了我们自己的定制事件,并了解了事件是如何引发和处理的。所以说事件封装了委托,委托封装了方法,这是正确的。因此,subscriber类不需要知道幕后发生了什么,它只需要publisher类通知事件已经引发,并必须作出相应响应。 我希望您在读完这篇文章后感到满意,并且在阅读和编写代码时感到最愉快。 我的其他系列文章: MVC: http://www.codeproject.com/Articles/620195/Learning-MVC-Part-Introduction-to-MVC-Architectu RESTful webapi: http://www.codeproject.com/Articles/990492/RESTful-Day-sharp-Enterprise-Level-Application 编码快乐! 本文转载于:http://www.diyabc.com/frontweb/news2012.html

原文地址:https://www.cnblogs.com/Dincat/p/13456863.html