Подтвердить что ты не робот

Как предотвратить изменение событий, связанных с изменением формы при инициализации формы в .NET?

Рассмотрим простую форму .NET с несколькими переключателями и флажком.

Каждый из переключателей имеет проверочную настройку CheckedChanged, которая выполняет некоторые действия на основе состояния флажка.

Моя проблема в том, что когда я инициализирую стандартную радиообъектуру, которую нужно проверить (из окна свойств конструктора), событие CheckedChanged запускается для этого переключателя, но флажок еще не инициализирован, поэтому я либо получаю нулевой указатель исключение или неправильное значение используется в обработчике. В любом случае, я не хочу, чтобы этот код обработчика запускался, если пользователь не выбирает переключатель после загрузки формы.

В настоящее время я обойду это, не инициализируя радиокнопку, но мне нужно установить этот вариант по умолчанию, и лучшее место у дизайнера. Я также могу добавить логическое поле, которое не установлено в true, пока форма не будет полностью загружена и не обработает события, если это ложь, но это грязный хак.

Что я могу сделать, чтобы предотвратить выполнение обработчиком этого кода?

4b9b3361

Ответ 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

Я, вероятно, нарушаю кучу правил, но это работает для меня.