2011-04-23 30 views
0

我在阅读这个 http://msdn.microsoft.com/en-us/library/bb882534.aspx如何使用自定义事件访问在C#中添加事件时要调用的方法?

目前还不清楚我该怎么做。

更新:由于一些人已经回答了这些主持人如何假装问题是含糊!

+0

不清楚你将如何做什么?这篇文章非常清楚地解释了它,它只是将订阅包装在访问器中。 – 2011-04-23 16:46:37

+1

这是我不明白什么是不明确的给你。你没有解释它。 – 2011-04-23 16:50:29

+0

由于有些人已经回答了这些版主如何假装问题是模糊的? – user310291 2011-05-22 20:46:57

回答

4

这里是你如何处理自定义事件访问一个简单的例子,我知道你是想每一个事件处理程序附加时间/从事件分开来调用一个函数。在这种情况下,你需要创建下面的代码的私人后盾代表myCustomEventDelegate,并让您的自定义事件访问add/remove块添加/删除处理程序委托,当然调用您的附加功能。

在这个例子中,我只是写入控制台,当然如果你的代码是一个库的一部分,那么这可不是一个好主意,它可能用于不同类型的应用程序,而这些应用程序可能无法访问控制台,但它毕竟只是一个例子。

using System; 

namespace CustomEventDemo 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     TheClassExposingYourEvent instance = new TheClassExposingYourEvent(); 

     instance.MyCustomEvent += new EventHandler<EventArgs>(Program_MyCustomEvent); 
     instance.DoSomething(); 
     instance.MyCustomEvent -= new EventHandler<EventArgs>(Program_MyCustomEvent); 

     Console.ReadKey(); 
    } 

    static void Program_MyCustomEvent(object sender, EventArgs e) 
    { 
     Console.WriteLine("The event was fired"); 
    } 
    } 

    class TheClassExposingYourEvent 
    { 
    private EventHandler<EventArgs> _myCustomEventDelegate; 
    public event EventHandler<EventArgs> MyCustomEvent 
    { 
     add 
     { 
     _myCustomEventDelegate += value; 
     // Do something extra here. 
     // Writing to the console is a bad example!!! 
     Console.WriteLine("Event handler attached"); 
     } 
     remove 
     { 
     _myCustomEventDelegate -= value; 
     // Do something extra here. 
     // Writing to the console is a bad example!!! 
     Console.WriteLine("Event handler detached"); 
     } 
    } 

    public void DoSomething() 
    { 
     if (_myCustomEventDelegate != null) 
     { 
     _myCustomEventDelegate(this, EventArgs.Empty); 
     } 
    } 
    } 
} 
+0

非常感谢你会阅读其他答案,看看哪一个最适合我。 – user310291 2011-04-23 18:47:21

1

难道不是这样吗?

event EventHandler IDrawingObject.OnDraw 
    { 
     add 
     { 
      lock (PreDrawEvent) 
      { 
       PreDrawEvent += value; 
      } 
      YourFunction(); // HERE 
     } 
+0

这就是我的想法。 – user310291 2011-04-23 18:48:18

1

事件实际上是通过添加/删除访问器进行封装​​以限制外部类如何修改委托的非公开委托。下面的代码虽然冗长,但详细解释了代表和事件。它来自我为同事试图学习.Net的一个示例项目。像书一样从上到下阅读(注释已添加说明,但代码编译):

// http://msdn.microsoft.com/en-us/library/aa288459(VS.71).aspx 

// delegates are a lot like function pointers and events "appear" to be a lot like delegates. 
// in a sense, a delegate is a function pointer class. below is an example declaration 
// of a delegate with an int return value, and two parameters (bool, string) 
public delegate int MyDelegate(bool abool, string astring); 

// delegates behind the scenes are actually of the System.MulticastDelegate type, and therefore 
// can have multiple invocations. 
// see http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx 

class DelegatesAndEvents 
{ 

    // delegates can also be defined inside classes 
    public delegate void AnotherDelegate(); 

    // Delegates can be instantiated just like any variable or field 
    public AnotherDelegate DelegateInstance; 

    public DelegatesAndEvents() 
    { 
     // add method/delegate to the invocation list 
     DelegateInstance += Method; 
     // or another syntax 
     DelegateInstance += new AnotherDelegate(Method); 

     // remove a method/delegate to the invocation list 
     DelegateInstance -= Method; 
     // or the more formal syntax 
     DelegateInstance -= new AnotherDelegate(Method); 

     // set the invocation list to a single method/delegate 
     DelegateInstance = Method; 
     // or the more formal syntax 
     DelegateInstance = new AnotherDelegate(Method); 

     // to clear a delegate, assign it to null: 
     DelegateInstance = null; 

     // for all the previous operators, its very important to note 
     // that they instantiate a new MulticastDelegate in the process. 
     // this means that every add (+=) or remove(-=) generates a new 
     // MulticastDelegate. Look at the following scenario: 
     DelegateInstance = Method; 

     // invoking a will call Method 
     AnotherDelegate a = DelegateInstance; 

     DelegateInstance += AnotherMethod; 
     // now, invoking a will still only invoke Method, while 
     // invoking DelegateInstance will invoke both Method 
     // and AnotherMethod. 

     // NOTE NOT BEST PRACTICE SEE BELOW 
     a(); // invokes Method 
     DelegateInstance(); // invokes Method and AnotherMethod 

     // The main importance of this fact deals with thread safety 
     // when invoking delegates. When invoking a delegate, you 
     // should always do a null-check before invocation to avoid 
     // an exception: 

     // NOTE NOT BEST PRACTICE SEE BELOW 
     if (a != null) 
     { 
      a(); 
     } 

     // the problem with the above code is that if another thread removes 
     // Method from a, after the null check, trying to invoke a will throw 
     // an exception. To get around this, since we stated before that the 
     // remove operation recreates the MulticastDelegate, assigning the 
     // delegate to a temporary delegate before doing the null check, and 
     // then invoking that temporary delegate should avoid threading problems 

     //************************************************************** 
     // NOTE THIS IS BEST PRACTICE FOR INVOKING A DELEGATE/EVENT 
     // This is thread-safe 
     AnotherDelegate aCopy = a; 
     if (aCopy != null) 
     { 
      aCopy(); 
     } 
     //************************************************************** 
    } 

    // NOTE there is a way to avoid having to worry about null checking, with only 
    // a small overhead. assigning a delegate/event to an initial no-op function will 
    // simplify how it is invoked: 

    public AnotherDelegate ThirdDelegate = delegate { }; // this assigns a no-op delegate 

    // using this method, you'll be able to call the delegate without checking for 
    // null or use a temporary variable. this of course is only true if no code 
    // sets ThirdDelegate to null anywhere. 

    public void Method() 
    { 
     // Delegates can be instantiated just like any variable or field 
     MyDelegate x = AFunction; // shorthand way of creating a delegate from an actual function 
     x = new MyDelegate(AFunction); // the more formal way of creating a delegate 

     // if a delegate hasn't been assigned anything, trying to call it will throw an exception 
     // not really necessary here though since we just assigned it 
     if (x != null) 
     { 
      int somevalue = x(false, "10"); 
     } 
    } 

    public void AnotherMethod() 
    { 
     // Do Nothing 
    } 

    public int AFunction(bool somebool, string somestring) 
    { 
     if (somebool) 
     { 
      return 1; 
     } 
     int avalue; 
     if (int.TryParse(somestring, out avalue)) 
     { 
      return avalue; 
     } 
     return 0; 
    } 

    // EVENTS 

    // events are types as delegates but avoid a couple of issues with 
    // instantiating delegates as members of a class. unlike delegates 
    // events can only be created within a class or struct (ie not as 
    // a standalone type in a namespace). to create an event, add the 
    // event keyword: 

    public event AnotherDelegate AnotherEvent; 

    // the above is actually the shorthand way of instantiating an event 
    // the full way is below: 

    private MyDelegate someEvent; 
    public event MyDelegate SomeEvent 
    { 
     add 
     { 
      someEvent += value; 
     } 
     remove 
     { 
      someEvent -= value; 
     } 
    } 

    // EXPLANATION OF HOW AN EVENT DIFFERS FROM A DELEGATE 
    // events are actually similar to properties in that they wrap a 
    // non-public delegate. this prohibits an external source from 
    // doing two things that most likely aren't desired: 
    // external code can't invoke the delegate 
    // external code can't do: classInstance.SomeEvent(...parameters...); 
    // external code can't set the delegate 
    // external code can't do: classInstance.SomeEvent = somedelegate; 
    // this effectively makes an event something that occurs within class, and 
    // controlled by the class, but can be subscribed to by external code. 

    // events usually derive from the EventHandler or EventHandler<T> delegates 
    // which have the following definitions: 
    // void EventHandler(object sender, EventArgs e) 
    // void EventHandler<T>(object sender, T e) 
    // the common way to use these is to always send the class instance that 
    // raised the event, as well as some event arguments that contain more 
    // information about the event. see below for an example of extending 
    // EventArgs. 

    public event EventHandler<TakeOffEventArgs> TakeOff; 
    public void PerformTakeOff() 
    { 
     EventHandler<TakeOffEventArgs> takeOffTemp = TakeOff; 
     if (takeOffTemp != null) 
     { 
      takeOffTemp(this, new TakeOffEventArgs("Spaceship", double.MaxValue)); 
     } 
    } 
} 

public class TakeOffEventArgs : EventArgs 
{ 
    public TakeOffEventArgs(string aircraft, double speed) 
    { 
     Aircraft = aircraft; 
     Speed = speed; 
    } 

    public string Aircraft { get; set; } 
    public double Speed { get; set; } 
} 
+0

感谢所有样品将就一下吧,看哪个答案是最适合我。 – user310291 2011-04-23 18:47:59