2011-04-23 69 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