[英]Issue in CheckedChanged event
我有一個復選框,並且已經訂閱了CheckedChanged事件。 處理程序在其中執行一些操作。 我以編程方式選中和取消選中該復選框(例如: chkbx_Name.Checked = true
),並觸發了CheckedChanged事件。
我希望僅在手動選中或取消選中它時才觸發此事件。 當我以編程方式選中/取消選中該事件時,有什么方法可以避免觸發此事件?
取消訂閱活動之前,請先進行以下設置:
check1.CheckChanged -= check1_CheckChanged;
那么您可以通過編程方式設置該值,而無需復選框觸發其CheckChanged事件:
check1.Checked = true;
然后重新訂閱:
check1.CheckChanged += check1_CheckChanged;
[編輯:2012年3月29日]
Tanvi方法的問題是您需要捕獲所有手動檢查或取消檢查的來源。 並不是有太多(僅來自於鼠標單擊和用戶按下空格鍵),但是您必須考慮從MouseClick和KeyUp調用重構事件(檢測空格鍵)
CheckBox(與此相關的任何控件)與用戶輸入(鍵盤,鼠標等)的來源無關,因此更為簡潔,因此,我將使CheckBox的編程設置真正具有編程性。 例如,您可以將屬性的編程設置包裝到擴展方法中:
static class Helper
{
public static void SetCheckProgrammatically(
this CheckBox c,
EventHandler subscribedEvent, bool b)
{
c.CheckedChanged -= subscribedEvent; // unsubscribe
c.Checked = b;
c.CheckedChanged += subscribedEvent; // subscribe
}
}
使用這種方法,您的代碼僅可以通過一個事件(即通過CheckChanged)對用戶的鼠標輸入和鍵盤輸入做出巧妙的響應。 無需重復代碼,無需預訂多個事件(例如,鍵盤,通過按空格鍵選中/取消選中CheckBox)
不會。只要屬性值發生更改,這些屬性更改事件就會觸發,而不管這是由代碼,由控件自己的代碼還是由數據綁定完成的。 通常,它們都是相同的代碼路徑。
但是,如果事件處理程序與更改屬性值的代碼位於同一類中,那么您可以做的是在該類中引入一個私有布爾字段,您可以將其用作指示當前屬性更改是否由以下屬性觸發的指標您的代碼或由用戶。 更改后,您只需重置它即可。 然后,事件處理程序將查看該字段並決定是否應該執行任何操作:
class Foo : Form {
private bool checkedProgrammatically = false;
void someMethod() {
// ...
checkedProgrammatically = true;
checkBox1.Checked = true;
checkedProgrammatically = false;
// ...
}
private void checkBox1_CheckChanged(object sender, EventArgs e) {
if (checkedProgrammatically) return;
// ...
}
}
抱歉,由於我是新來的(沒有聲譽),我不能只評論Michael Buen的回答,但是出於幾個原因,我非常希望他的解決方案比JohannesRössel的解決方案好。
1)checkedProgrammatically變量對我來說有點接近全局變量。 沒有什么可以阻止另一種方法意外將其設置為true,從而導致所有事件停止。
2)根據要處理的事件數,最終可能會有很多變量。 更改錯誤的代碼很容易,結果也很難調試。
3)當您取消訂閱然后重新訂閱時,您正在做什么。 所有邏輯就在那里,您無需更改事件處理程序即可根據特定條件提早退出。
我已經廣泛使用了這兩種方法,從長遠來看,我發現Michael的使用要容易得多。
您可以使用MouseClick事件,並在其中檢查復選框的已選中狀態。 這樣,就不會以編程方式觸發它,只有在用戶手動選中或取消選中復選框時才會調用它。
您可以在以編程方式更改值之前設置布爾變量,並在checkedchanged事件中檢查並重置該變量
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.