2013-05-28 29 views
0

我正在綁定Process的Exited事件。對於該事件,我有一個複選框,用於確定在運行Exited事件時會發生什麼情況。如果我在進程運行時選中複選框,它將獲取進程並添加已退出的事件。如果進程未運行,則啓動進程並添加已退出的事件。如果複選框未選中,無論Process是否正在運行,我什麼也不做。我的問題是,如果進程正在運行,並且我檢查框(它得到一個事件),取消選中框(沒有任何設計發生),並重新檢查框,然後進程獲得兩個退出事件(即是完全相同的方法)。如果我有Process對象,如果它已經有一個Exited事件,我怎麼不能添加它?確保只有一個代表與事件相關聯?

+1

你可以發表你如何註冊已退出事件的事件處理程序相關的代碼? –

+0

似乎有些可疑,您需要與委託人一起確定有多少個處理程序已註冊。也許你可以只註冊一次,然後在函數內部根據複選框的當前值確定是否運行? – deepee1

+0

聽起來像你需要一個已經註冊的標誌,或者使用委託而不是事件。委託人一次只能爲其分配一個方法。 –

回答

1

您可以使用-=運算符分離代表事件。

就像你會做這一個事件綁定到委託:

EventHandler foo = new EventHandler(this._onClick) 
myButton.Click += foo; 

你也可以做到這一點,如果你一直某處參考:

myButton.Click -= foo; 

然後當事件被觸發不再調用foo。

你可能在做什麼,當複選框被選中,是這樣的:

foo.Exited += new EventHandler(your_method); 

這樣,每次你選中該複選框,你會得到一個新的處理程序綁定到事件。只使用一個處理程序。這樣,當取消選中複選框時,您可以將之前與退出事件關聯的代理人-=

編輯:因爲所有你想要的是保持委託引用的方法不做任何事情,爲什麼不把委託綁定到檢查事件以外的某個點上,然後使用該方法中的複選框狀態用於選擇是運行方法的其餘部分,還是使用過早返回來暫停它?

+0

當取消選中該複選框時,該事件仍應與其綁定。當複選框被重新檢查時,我希望不註冊第二個EventHandler。 –

+1

@Corey然後在類級別添加一個布爾值,表明該事件已被分配。如果已設置,請勿再次分配。 –

0

要獲得訂閱邀請的所有代理的數組,只需使用GetInvoacationList方法。從那裏你可以檢查它的長度或迭代它來檢查事件將調用多少/哪個委託。

Delegate[] delegates = MyEvent.GetInvocationList(); 

根據你實際上想要做的事情,你似乎可以做一些事情;

if (MyEvent.GetInvocationList().Length > 0) 

if (MyEvent.GetInvoationList().Contains(referenceToMyDelegate)) 
+0

這不是我的事件。我無法訪問進程的已退出調用列表。 –

0

試試這個:

delegate void MyDelegate(string message); 

class Foo 
{ 
    MyDelegate _delegate = null; 
    int _count = 0; 

    public event MyDelegate MySingleDelegateEvent 
    { 
     add 
     { 
      if (_count == 0) 
      { 
       _delegate += value; 
       _count++; 
      } 
     } 
     remove 
     { 
      if (_delegate != null) 
      { 
       _delegate -= value; 
       _count--; 
      } 
     } 
    } 
} 
0

如果你一定要窺探你可以使用反射事件:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var car = new Car(); 
     car.Stopped += car_Stopped; 
     var evt = car.GetType().GetEvent("Stopped"); 
     if(evt == null) //evt will be null if nothing is registered to the event 
      car.Stopped += car_Stopped; 

     car.Stop(); //Prints 'Stopped!' only once 

     Console.ReadLine(); 
    } 

    static void car_Stopped(object sender, EventArgs e) 
    { 
     Console.WriteLine("Stopped!"); 
    } 
} 

class Car 
{ 
    public event EventHandler<EventArgs> Stopped; 
    protected void OnStopped() 
    { 
     var temp = Stopped; 
     if(temp != null) 
      Stopped(this, new EventArgs()); 
    } 
    public void Stop() 
    { 
     OnStopped(); 
    } 
} 
+0

我的確喜歡這種方法,但在.Net庫中使用Reflection類型看起來好像很難。儘管如此,與其他答案相比,這似乎是可行的。 –

+0

@Corey只需在訂閱(+ =)之前立即取消訂閱( - =)。如果您退訂您之前沒有訂閱的活動,它不會拋出。 –

相關問題