Обнаружение изменения любого из элементов управления в групповом поле

У меня есть кнопка «Применить» в форме, которая изначально имеет свойство Enabled = False, но при изменении элемента управления в любом GroupBox на странице from должно быть установлено Enabled = True.

У меня есть несколько элементов управления GroupBox в форме, и я надеялся, что смогу просто проверить, изменился ли элемент управления в каком-либо из них. Однако, хотя кажется, что вы можете подключиться к событиям ControlAdded и ControlRemoved, события ControlChanged нет.

Итак, в настоящее время я настраиваю это, как показано ниже (на самом деле нужно проверить гораздо больше, чем 5 элементов управления).

Есть ли более эффективный способ сделать это, так как я вижу, что это вызовет проблемы в будущем (например, если параметры когда-либо будут добавлены в группу)? Спасибо.

Private Sub ControlChanged(sender As Object,
                           e As EventArgs) Handles txtUsername.KeyUp,
                                                   chkRestoreIEFavourites.CheckedChanged,
                                                   chkRestoreNicknames.CheckedChanged,
                                                   chkRestoreDesktop.CheckedChanged,
                                                   chkRestoreQuickLaunch.CheckedChanged
    Me.btnApply.Enabled = True
End Sub

person David Gard    schedule 10.01.2014    source источник
comment
Если это просто варианты, которые будут работать, но если событие CheckChanged для данного Chk должно когда-либо что-то делать само по себе, вы использовали для этого его событие. В этом случае, вероятно, было бы лучше включить кнопку как часть события проверки. KeyUp тоже кажется странным выбором для ТБ   -  person Ňɏssa Pøngjǣrdenlarp    schedule 10.01.2014
comment
К сожалению, в настоящее время я не подключаюсь к событиям от всех элементов управления, которые должны быть проверены для этой цели, поэтому я не могу реализовать первую часть вашего предложения. Кроме того, насколько KeyUp странный выбор? Спасибо.   -  person David Gard    schedule 10.01.2014
comment
KeyUp будет срабатывать при каждом нажатии клавиши. Это может быть backspace, табуляция, клавиша возврата. Другими словами, вы должны включить кнопку, в то время как в текстовом поле может вообще не быть текста. Это может не быть проблемой в вашем случае, в зависимости от любой другой проверки, которую вы можете выполнить. Возможно, .TextChanged было бы лучшим событием.   -  person Mych    schedule 10.01.2014
comment
Итак, в основном событие KeyUp текстового поля сработает, если я выйду из этого поля, а в случае TextChanged этого не произойдет? Достаточно справедливо, я постараюсь внести некоторые поправки в свой код. Спасибо.   -  person David Gard    schedule 10.01.2014


Ответы (1)


Увы, я нашел способ сделать это...

Ниже теперь добавлены обработчики (на Shown), так что если какие-либо CheckBox или TextBox в пределах GroupBox в форме изменены, кнопка Apply устанавливается на Enabled = True. Я также удаляю ручки, когда значение from равно Closing.

Является ли это лучшим способом сделать это, я не знаю, но пока это единственный известный мне способ. Комментарии приветствуются!

Private Sub formSettings_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    SetupChangeHandlers()
End Sub

Private Sub formSettings_Closing(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Closing
    SetupChangeHandlers(Remove:=True)
End Sub

Private Sub SetupChangeHandlers(Optional ByVal Remove As Boolean = False)

    For Each GroupBox As GroupBox In Me.sptSettings.Panel2.Controls.OfType(Of GroupBox)() _
                                       .OrderBy(Function(b) b.TabIndex)
        For Each Control As Control In GroupBox.Controls.OfType(Of Control)() _
                                       .OrderBy(Function(b) b.TabIndex)

            If TypeOf Control Is CheckBox Then
                Dim Checkbox = CType(Control, CheckBox)
                If Not Remove Then : AddHandler Checkbox.CheckedChanged, AddressOf GroupBoxControl_Changed
                Else : RemoveHandler Checkbox.CheckedChanged, AddressOf GroupBoxControl_Changed
                End If

            ElseIf TypeOf Control Is TextBox Then
                Dim TextBox = CType(Control, TextBox)
                If Not Remove Then : AddHandler TextBox.TextChanged, AddressOf GroupBoxControl_Changed
                Else : RemoveHandler TextBox.TextChanged, AddressOf GroupBoxControl_Changed
                End If

            ElseIf TypeOf Control Is MaskedTextBox Then
                Dim MaskedTextBox = CType(Control, MaskedTextBox)
                If Not Remove Then : AddHandler MaskedTextBox.TextChanged, AddressOf GroupBoxControl_Changed
                Else : RemoveHandler MaskedTextBox.TextChanged, AddressOf GroupBoxControl_Changed
                End If

            End If
        Next
    Next

End Sub

Обратите внимание, что вам нужно будет импортировать System.Linq и System.Windows.Forms, чтобы использовать это решение.

person David Gard    schedule 10.01.2014