2010-06-30 89 views
17

考慮一個帶有幾個單選按鈕和一個複選框的簡單.NET表單。如何防止在.NET中進行表單初始化時觸發值更改事件?

每個單選按鈕都有一個CheckedChanged處理程序設置,該設置根據複選框的狀態執行某些操作。

我的問題是,當我初始化默認的單選按鈕被檢查(從設計器屬性窗口)CheckedChanged事件觸發該單選按鈕,但複選框尚未初始化,所以我要麼null指針異常或在處理程序中使用了錯誤的值。無論哪種方式,我不希望該處理程序代碼運行,除非用戶在窗體加載後選擇一個單選按鈕。

我目前通過不初始化單選按鈕來解決這個問題,但是我最終需要設置該默認值,最好的地方是來自設計者。我還可以添加一個boolean字段,該字段在表單完全加載之前不會設置爲true,如果該值爲false則不處理事件,但這是一種骯髒的黑客行爲。

我該怎麼做才能防止處理程序運行其代碼?

+0

這是一個明確的Visual Studio錯誤,在我看來。設置一個初始化標誌(如x77的答案)是最簡單的解決方法,但它應該由編譯器負責。 – xpda 2010-06-30 20:03:19

+0

這是一個已知的* bug /特性*。當您使用VS中的內置升級工具將VB6項目升級到VB.NET時,它實際上會在這些事件中插入UPGRADE_WARNING註釋。 (''UPGRADE_WARNING:事件TextBox1.TextChanged可能會在表單初始化時觸發.') – awe 2010-07-28 07:44:00

+0

對於後人,MSDN文章中有關如何處理@ awe的評論中引用的警告:https://msdn.microsoft.com/zh-cn/ us/library/26aab97z%28v = vs.71%29.aspx:set ** IsInitializing **「to ** true **在窗體的構造函數中,在** InitializeComponent **調用之前;將其設置爲** false **緊接電話後。「 – 2016-01-13 00:34:10

回答

16

「我也可以放置一個布爾型的字段,它在表單完全加載之前不會設置爲true,如果這是錯誤的,則不處理事件,但這是一種骯髒的黑客攻擊。」

這也是最簡單和最好的方式!

可以這麼說,.NET提供了一種簡潔的方式來打開和關閉所有事件處理程序,直到窗體被加載。即使只是你正在處理的。它仍然不夠靈活,禁用你想要啓用但禁用你沒有。通常,表單設置會發生,並且您希望事件觸發。此外,如果沒有事件觸發,表單將無法正確建立。

+9

仍然覺得髒:) – CodeFusionMobile 2010-06-30 15:48:54

+19

我寫了這個答案後,我不得不洗澡。 – FastAl 2010-06-30 16:34:35

3

簡單的解決方法是聲明初始化變量:

Private Initializing as boolean = True 

    Private Sub rb_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbNuevos.CheckedChanged, RbDesaparecidos.CheckedChanged, RbModificados.CheckedChanged, RbNoDesap.CheckedChanged, RbDesHoy.CheckedChanged, RbChT.CheckedChanged 
     if Initializing then return 

     'Your Code  
    End Sub 

    Public Sub New() 

     ' Llamada necesaria para el Diseñador de Windows Forms. 
     InitializeComponent()  
     ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 

     initializing = false 
    end sub 

最複雜的:從方法中刪除「手柄」,並在新的方法使用AddHandler

Public Sub New() 

     ' Llamada necesaria para el Diseñador de Windows Forms. 
     InitializeComponent()  
     ' Agregue cualquier inicialización después de la llamada a InitializeComponent(). 

     AddHandler RbChT.CheckedChanged, AddressOf rb_CheckedChanged 
    end sub 
+0

要添加新的方法:寫:「Sub New」並按回車 – x77 2010-06-30 16:07:15

23

爲了讓它感覺略少髒,如果在窗體的構造函數初始化該控件,你可能能夠使用形式IsHandleCreated屬性,而不是你自己的布爾檢查,如果它實際上應該驗證或不。
我會認爲,通常情況下,你不想在第一次顯示它之前驗證任何東西,並且直到它沒有創建句柄。

代碼示例:

Private Sub myRadioButton_CheckedChanged(sender As Object, e As EventArgs) Handles myRadioButton.CheckedChanged 
If myRadioButton.Checked AndAlso myRadioButton.IsHandleCreated Then 
    'Do Work 
End If 
End Sub 
+1

是的,這是不太髒,它的工作原理!我遇到了同樣的問題,並在事件中檢查「IsHandleCreated」形式解決了所有問題! – awe 2010-07-29 08:20:07

+1

這應該是答案。 – Sire 2014-12-22 14:24:47

0

有一件事我發現,工作原理是將事件加載表格後手動。

爲此,您可以簡單地進入在該表單的設計器文件中找到的生成表單代碼,並拉出添加事件的行。這將是這個樣子:

this.controlName.CheckedChanged += new System.EventHandler(this.controlName_CheckedChanged); 

然後把所有這些調用到您在窗體的構造函數中InitializeComponent調用後調用一個方法。

+0

我會小心,因爲如果你在設計器類中弄亂了代碼,你可能會以醜陋的方式破壞你的表單。它應該工作,但經常備份以防萬一! – 2016-07-19 18:44:36

-3

我把一個公共變量在模塊1文件 昏暗公共bolForm_LoadingTF布爾=真

在每個formLoad事件我把 bolForm_LoadingTF =真

在具有OnSelectedIndexChanged 事件每個控件我把若bolForm_LoadingTF =真然後退出子

在形式負載事件的結束我把 bolForm_LoadingTF =假

我可能打破了一堆規則,但這對我來說 。

-1

也許某些功能可以使用click事件而不是檢查更改的事件。

1

還有一種方法:

Private Sub dgvGroups_CellValueChanged(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvGroups.CellValueChanged 

    If Me.Visible = False Then Exit Sub ' Sub gets called on form load which causes problems 

    wksGroups.Cells(e.RowIndex + 1, 1) = dgvGroups.Item(e.ColumnIndex, e.RowIndex).Value 
    wksGroups.Cells(1, 5) = dgvGroups.RowCount 
2

對於radiobutton看到Hans Olsson answer

對於數字上下,像這樣做

Private Sub myNumeric_ValueChanged(sender As Object, e As EventArgs) Handles myNumeric.ValueChanged 
     If myNumeric.Value >= 0 AndAlso myNumeric.IsHandleCreated Then 
      'Do the work 
     End If 
End Sub 

的關鍵詞是myNumeric.ValueIsHandleCreated

+1

'IsHandleCreated'是這裏的訣竅,比布爾黑客IMO更好。我在'ValueChanged'處理程序中使用'If CType(sender,NumericUpDown).IsHandleCreated Then ...'。 – Nepaluz 2017-01-23 16:37:36

0

剛在任何情況下ne仍然在搜索這個事件在初始化表單時被觸發但是表單不可見,也就是說你有一個外鍵關係,你有一個缺省值需要的問題,每一行更新都會被觸發。所以下面的代碼爲我工作....

if (Visible && !(e.ColumnIndex == 0)) 
     { 
      phoneEdited = true; 
      MessageBox.Show("A Phone entry has been entered"); 
     } 
相關問題