Как предотвратить изменение событий, связанных с изменением формы при инициализации формы в .NET?
Рассмотрим простую форму .NET с несколькими переключателями и флажком.
Каждый из переключателей имеет проверочную настройку CheckedChanged, которая выполняет некоторые действия на основе состояния флажка.
Моя проблема в том, что когда я инициализирую стандартную радиообъектуру, которую нужно проверить (из окна свойств конструктора), событие CheckedChanged запускается для этого переключателя, но флажок еще не инициализирован, поэтому я либо получаю нулевой указатель исключение или неправильное значение используется в обработчике. В любом случае, я не хочу, чтобы этот код обработчика запускался, если пользователь не выбирает переключатель после загрузки формы.
В настоящее время я обойду это, не инициализируя радиокнопку, но мне нужно установить этот вариант по умолчанию, и лучшее место у дизайнера. Я также могу добавить логическое поле, которое не установлено в true, пока форма не будет полностью загружена и не обработает события, если это ложь, но это грязный хак.
Что я могу сделать, чтобы предотвратить выполнение обработчиком этого кода?
Ответы
Ответ 1
"Я также могу поместить логическое поле, которое не установлено в true, пока форма не будет полностью загружена и не обработает события, если это ложь, но это грязный хак."
Это также легкий и лучший способ сделать это!
Предположим, что .NET обеспечивает опрятный способ включения и выключения всех обработчиков событий до тех пор, пока форма не будет загружена. Даже те, с кем вы работаете. Было бы недостаточно гибко отключить то, что вы хотели включить, но отключить то, что вы не сделали. Часто происходят установки формы, и вы хотите, чтобы события срабатывали. Кроме того, форма не будет строиться правильно, если нет событий.
Ответ 2
Чтобы сделать его немного менее грязным, если вы инициализируете элементы управления в конструкторе формы, вы можете использовать формы IsHandleCreated, а не ваш собственный bool, чтобы проверить, действительно ли это нужно проверить или нет.
Я бы подумал, что обычно вы не хотите проверять что-либо прежде, чем оно будет показано в первый раз, и дескриптор не будет создан до тех пор, пока он не будет.
Пример кода:
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
Ответ 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
Ответ 4
Еще один способ:
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
Ответ 5
Для radiobutton
см. ответ Ханса Ольсона
Для числового вниз, сделайте это так
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.Value
и IsHandleCreated
Ответ 6
Одна вещь, которую я обнаружил, что работы - это добавление событий вручную после загрузки формы.
Для этого вы можете просто перейти в сгенерированный код формы, найденный в файле конструктора этой формы, и вытащить строки, которые добавляют событие. Он будет выглядеть примерно так:
this.controlName.CheckedChanged += new System.EventHandler(this.controlName_CheckedChanged);
Затем поместите все эти вызовы в метод, который вы вызываете после вызова InitializeComponent в конструкторе формы.
Ответ 7
На всякий случай, если кто-то все еще ищет это, событие запускается при инициализации формы. НО форма еще не видна. Также скажите, что у вас есть отношение внешнего ключа, по которому у вас есть значение по умолчанию, которое требуется для каждой проблемы обновление строки тоже. Поэтому для меня работал следующий код....
if (Visible && !(e.ColumnIndex == 0))
{
phoneEdited = true;
MessageBox.Show("A Phone entry has been entered");
}
Ответ 8
Возможно, для некоторых функций вы можете использовать событие click вместо проверки изменений.
Ответ 9
Я помещаю публичную переменную в файл Module1
Dim Public bolForm_LoadingTF как Boolean = True
В каждом событии formLoad
bolForm_LoadingTF = True
В каждом элементе управления с OnSelectedIndexChanged
событие, которое я поставил, если bolForm_LoadingTF = True, тогда Exit Sub
В конце формы загружается событие I
bolForm_LoadingTF = False
Я, вероятно, нарушаю кучу правил, но это работает
для меня.