События флажка при открытии и закрытии формы срабатывают при перезагрузке формы

Во-первых... Я готов содрать шкуру с этого кота по-другому, если с самого начала сделаю это неправильно. Используя VB 2010 .net 4.0, я очень новичок.

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

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

Основная форма Код флажка для установки логических значений и увеличения или уменьшения переменной промежуточного итога наиболее часто используемых продуктов.

    Private Sub chkbox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox1.CheckedChanged
    If chkbox1.Checked = True Then
        bChkbox1 = True
        Subtotal += 15
    Else
        bChkbox1 = False
        Subtotal -= 15
    End If
End Sub

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

    Private Sub btnAllProducts_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAllProducts.Click
    Form3.Show()
End Sub

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

Private Sub chkbox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox2.CheckedChanged
    If chkbox2.Checked = True Then 'also tried without the nested if with same results
        If Me.IsHandleCreated = True Then 'me.visible behaves the same way
            MsgBox("form visible true")'launches after clicking button but before form is actually on screen
            Form1.bcheckbox2 = True
            Form1.Subtotal += 105
        End If
    Else
        Form1.bcheckbox2 = False
        Form1.Subtotal -= 105
    End If
End Sub

Булевы значения используются для установки флажков, которые были отмечены на главной странице или когда она была открыта ранее.

    If Form1.bcheckbox2 = True Then
        chkbox2.Checked = True
    End If

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

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


person Rodger    schedule 23.11.2013    source источник


Ответы (2)


Нередко приходится сообщать чекам и радио об игнорировании событий при загрузке формы. Вам просто нужен флаг «Игнорировать» или «Загружено»:

Public Class Form1
   Private ignore As Boolean = True
   ...

 Private Sub Form1_Load(...
    ' do normal stuff

    ignore = False               ' should be the ONLY place it is set
 End Sub

Private Sub CheckBox2_CheckedChanged(...
   If ignore Then Exit Sub

End Sub

Код конструктора форм запускает события по мере создания формы и элементов управления, что МОЖЕТ быть удобно для инициализации, но часто вызывает проблемы. Некоторые элементы управления даже получат одно и то же событие дважды. На самом деле не существует действия «перезагрузка» для форм. Если вы их скроете, Show() больше не будет запускать событие Load.

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

person Ňɏssa Pøngjǣrdenlarp    schedule 23.11.2013
comment
Что вы имеете в виду под созданием экземпляров форм и почему это вместо .show? - person Rodger; 24.11.2013
comment
приятно слышать... Form1.Show является неявным созданием экземпляров, Dim frm As New Form1 // frm.Show создает INSTANCE формы, рассматривая его как класс, которым они являются, и создает из них правильные объекты. Помимо прояснения разницы между классом и объектом, он позволяет вам контролировать область действия каждого экземпляра формы. - person Ňɏssa Pøngjǣrdenlarp; 24.11.2013
comment
ах, так что, если у меня явно установлен параметр, то form1.show даже не будет работать? И поскольку это рекомендуемая настройка для явной опции, мне нужно будет изменить ее, когда я включу ее? - person Rodger; 24.11.2013
comment
Нет, неявные ссылки разрешены, просто не рекомендуется. Некоторые разработчики даже не знают, что существует старая форма по умолчанию (см. комментарии здесь: stackoverflow.com/q/20076969/1070452) . Используя явную ссылку, я могу создать экземпляр frm и показать его там, где хочу, и никто другой не сможет получить к нему доступ. Метод по умолчанию просто вызывает проблемы, чем сложнее проблема - сортировка их - обычная проблема здесь. - person Ňɏssa Pøngjǣrdenlarp; 24.11.2013

Если кто-то ищет альтернативу или имеет аналогичную проблему, вот мой обходной путь для обнаружения изменения события, чтобы флажок не срабатывал при повторной загрузке:

    If ((Me.CheckBox2.Value <> Sheets(1).Range("t6").Value) And (Me.CheckBox2 = True)) = True Then
' do your stuff
Me.CheckBox2.Value = False
Else
Me.CheckBox2.Value = True
End If

Где Sheets(1).Range("t6").Value - это то место, где хранится значение checkbox2. У меня это назначено для ввода msgbox, поэтому, когда запускается событие vbno, выполняется else.

Ваше здоровье.

person Bloodrazor    schedule 10.05.2020