我正在綁定Process的Exited事件。對於該事件,我有一個複選框,用於確定在運行Exited事件時會發生什麼情況。如果我在進程運行時選中複選框,它將獲取進程並添加已退出的事件。如果進程未運行,則啓動進程並添加已退出的事件。如果複選框未選中,無論Process是否正在運行,我什麼也不做。我的問題是,如果進程正在運行,並且我檢查框(它得到一個事件),取消選中框(沒有任何設計發生),並重新檢查框,然後進程獲得兩個退出事件(即是完全相同的方法)。如果我有Process對象,如果它已經有一個Exited事件,我怎麼不能添加它?確保只有一個代表與事件相關聯?
回答
您可以使用-=
運算符分離代表事件。
就像你會做這一個事件綁定到委託:
EventHandler foo = new EventHandler(this._onClick)
myButton.Click += foo;
你也可以做到這一點,如果你一直某處參考:
myButton.Click -= foo;
然後當事件被觸發不再調用foo。
你可能在做什麼,當複選框被選中,是這樣的:
foo.Exited += new EventHandler(your_method);
這樣,每次你選中該複選框,你會得到一個新的處理程序綁定到事件。只使用一個處理程序。這樣,當取消選中複選框時,您可以將之前與退出事件關聯的代理人-=
。
編輯:因爲所有你想要的是保持委託引用的方法不做任何事情,爲什麼不把委託綁定到檢查事件以外的某個點上,然後使用該方法中的複選框狀態用於選擇是運行方法的其餘部分,還是使用過早返回來暫停它?
當取消選中該複選框時,該事件仍應與其綁定。當複選框被重新檢查時,我希望不註冊第二個EventHandler。 –
@Corey然後在類級別添加一個布爾值,表明該事件已被分配。如果已設置,請勿再次分配。 –
要獲得訂閱邀請的所有代理的數組,只需使用GetInvoacationList
方法。從那裏你可以檢查它的長度或迭代它來檢查事件將調用多少/哪個委託。
Delegate[] delegates = MyEvent.GetInvocationList();
根據你實際上想要做的事情,你似乎可以做一些事情;
if (MyEvent.GetInvocationList().Length > 0)
或
if (MyEvent.GetInvoationList().Contains(referenceToMyDelegate))
這不是我的事件。我無法訪問進程的已退出調用列表。 –
根據這一微軟論壇帖子http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/45071852-3a61-4181-9a25-068a8698b8b6/再次分配之前,你可以刪除現有的處理程序。
試試這個:
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--;
}
}
}
}
如果你一定要窺探你可以使用反射事件:
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();
}
}
我的確喜歡這種方法,但在.Net庫中使用Reflection類型看起來好像很難。儘管如此,與其他答案相比,這似乎是可行的。 –
@Corey只需在訂閱(+ =)之前立即取消訂閱( - =)。如果您退訂您之前沒有訂閱的活動,它不會拋出。 –
- 1. 如何將提交按鈕與只有一個值相關聯
- 2. SQL Server - 確保只有一個事務嘗試創建表
- 3. jquery - 如何確保只有一個事件執行結果
- 4. 如何將按鈕事件與唯一控件相關聯?
- 5. 只更新表格,但表格與另一個表格關聯
- 6. 將一個表與「hasMany」其他表相關聯
- 7. 如何將關鍵事件與dojo中TreeGrid的行相關聯?
- 8. 關聯事件在SQL表
- 9. 確保SQLite表只有一行
- 10. 創建與另一個表的ID相關聯的記錄 - 不保存
- 11. JPA: - 許多一對多隻有一個關聯表的外鍵
- 12. 如何確保有在C#中只有一個事件處理程序
- 13. 與C#中的一個文件相關聯的兩個CryptoStreams
- 14. 將日期與事件相關聯的事件與日期在SQL中
- 15. 與事件和反思相關的代表字段
- 16. 第二個表與第一個代碼的關聯
- 17. 在C文件中只有一個內聯函數是否相關?
- 18. 與OAuth相關聯
- 19. 如何正確關聯一個id生成器序列與表
- 20. 兩個相同的keydown事件;只有一個工程
- 21. 確保surfaceView或關聯的SurfaceHolder具有有效的表面
- 22. 如何僅將事件與一個對象關聯? jqplot
- 23. 只返回記錄沒有記錄關聯在另一個表
- 24. 如何最好地將代碼與jQuery中的事件相關聯?
- 25. 有一個表多個關聯
- 26. 確保事件的另一個
- 27. MYSQL如何確保多個關聯中
- 28. 將現有類與故事板相關聯
- 29. 如何將評論表單與正確的帖子相關聯
- 30. 如何將事件與微調選項相關聯
你可以發表你如何註冊已退出事件的事件處理程序相關的代碼? –
似乎有些可疑,您需要與委託人一起確定有多少個處理程序已註冊。也許你可以只註冊一次,然後在函數內部根據複選框的當前值確定是否運行? – deepee1
聽起來像你需要一個已經註冊的標誌,或者使用委託而不是事件。委託人一次只能爲其分配一個方法。 –