2012-08-26 264 views
1

我正在使用C#開發一個紙牌遊戲項目。在這個遊戲中,桌面上的牌需要訂閱纔會觸發大量事件。但是,我需要卡片動態訂閱和取消訂閱事件,以便當前不活動的卡片不會響應正在觸發的事件。動態訂閱/取消訂閱活動

我的解決方案是使用一個EventManager父類,每個事件有一個孩子。這些管理者中的每一個都會擁有以EventHandler作爲參數的訂閱/取消訂閱方法。被調用時,方法將從分配給該管理器的事件中訂閱/取消訂閱提供的處理程序。

下面的代碼是一個基本的控制檯應用程序,它使用與我的紙牌遊戲相同的設計模式,並且具有相同的問題。你可以直接將它粘貼到Visual Studio中,它會運行。

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var example = new ExampleCard(); 
      example.Subscribe(); 
      example.Events.FireEventOne(null, new EventArgs()); 
      example.UnSubscribe(); 
      example.Events.FireEventOne(null, new EventArgs()); 
      Console.ReadLine(); 
     } 
    } 

    public class EventContainer 
    { 
     public delegate void EventOne(Object sender, EventArgs r); 
     public event EventOne OnEventOne; 

     public EventContainer() 
     { 
      OnEventOne += Default_Handler; 
     } 

     public void Default_Handler(object sender, EventArgs e) 
     { 

     } 

     public void FireEventOne(object sender, EventArgs e) 
     { 
      OnEventOne(sender, e); 
     } 
    } 

    public class EventManager 
    { 
     protected EventContainer Events; 

     public EventManager(EventContainer events) 
     { 
      Events = events; 
     } 

     public virtual void Subscribe(EventHandler handler) 
     { 
     } 

     public virtual void Unsubscribe(EventHandler handler) 
     { 
     } 
    } 

    public class EventOneManager : EventManager 
    { 
     public EventOneManager(EventContainer events) 
      : base(events) 
     { 
     } 

     public override void Subscribe(EventHandler handler) 
     { 
      Events.OnEventOne += new EventContainer.EventOne(handler); 
     } 

     public override void Unsubscribe(EventHandler handler) 
     { 
      Events.OnEventOne -= new EventContainer.EventOne(handler); 
     } 
    } 

    public class ExampleCard 
    { 
     public EventContainer Events = new EventContainer(); 
     private readonly List<EventManager> _subscribedEvents = new List<EventManager>(); 

     public ExampleCard() 
     { 
      _subscribedEvents.Add(new EventOneManager(Events)); 
     } 

     public void Example_OnEventOneFired(object sender, EventArgs e) 
     { 
      Console.WriteLine("Event One was fired."); 
     } 

     public void Subscribe() 
     { 
      _subscribedEvents[0].Subscribe(Example_OnEventOneFired); 
     } 

     public void UnSubscribe() 
     { 
      _subscribedEvents[0].Unsubscribe(Example_OnEventOneFired); 
     } 
    } 
} 

EventOneManager.Subscribe()似乎工作,但EventOneManager.Unsubscribe()沒有;在調用該方法後,示例卡仍然訂閱了該事件,我無法弄清楚原因或解決方法。

有一兩件事我想是去掉「新EventContainer.EventOne」呼叫使它看起來像這樣:

public override void Unsubscribe(EventHandler handler) 
      { 
       Events.OnEventOne -= handler; 
      } 

但我得到這個錯誤:無法隱式轉換類型「System.EventHandler」到「ConsoleApplication1。 EventContainer.EventOne「有什麼建議?

另外我想能夠使用自定義的EventArgs類,但我不知道如何傳遞一個通用的處理程序,它將與我正在使用的任何事件。我可以解決這個問題,但我更喜歡使用自定義的EventArgs。

回答

1

您需要將事件更改爲EventHandler類型。
你不應該製作你自己的委託類型。

要傳遞更多數據,請使用EventHandler<T>

+0

完成並完成...你真棒謝謝! – peter9464