Форма открывается как модальное диалоговое окно закрывается при нажатии кнопки, даже если Close () не вызывается - PullRequest
1 голос
/ 29 октября 2010

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

Код, который создает диалог, довольно прост:

using(var frmSettings = new SettingsForm(configuration))
{
    frmSettings.ConfigurationChanged += ConfigurationChangedHandler;
    frmSettings.UnhandledException += UnhandledExceptionHandler;

    frmSettings.ShowDialog();
}

Класс SettingsForm в основном имеет три элемента управления GroupBox, с элементами управления Label и TextBox в каждом и 4 Button элементами управления внизу: "Advanced...", "Restore Defaults", "Cancel" и "Apply". Каждый TextBox имеет обработчик событий Validating, подключенный через конструктор. Каждая кнопка имеет обработчик Click, подключенный через конструктор. Каждый из них делает довольно очевидные вещи: открывает другое модальное диалоговое окно с более расширенными настройками, восстанавливает текстовые поля к их значениям по умолчанию, закрывает диалоговое окно или сохраняет изменения, запускает событие ConfigurationChanged и , затем закрывает диалоговое окно (но только если все поля действительны!).

В случае ошибки ввода формы я отменяю соответствующее событие Validating, устанавливая ((CancelEventArgs)e).Cancel = true. Однако поведение обеих форм по умолчанию состояло в том, что пользователь не мог изменить фокус при сбое проверки. Я нашел это довольно раздражающим и в конечном итоге нашел в конструкторе возможность автоматически проверять, когда пользователь покидает поле, но разрешать ему уходить, даже если проверка не удалась: AutoValidate = EnableAllowFocusChange. [1]

Моя "Apply" кнопка Click Обработчик выглядит в основном так:

private void btnApply_Click(object sender, EventArgs e)
{
    try
    {
        if(this.ValidateChildren())
        {
            this.Configuration.Field1 = this.txtField1.Text;
            this.Configuration.Field2 = this.txtField2.Text;
            this.Configuration.Field3 = this.txtField3.Text;

            if(this.Configuration.Changed)
            {
                this.Configuration.Save();

                this.OnConfigurationChanged(new ConfigurationChangedEventArgs(
                        this.Configuration));
            }

            this.Close();
        }
    }
    catch(Exception ex)
    {
        this.OnUnhandledException(new UnhandledExceptionEventArgs(
                "Failed To Apply Configuration Settings",
                ex));
    }
}

В настоящее время я тестирую код, разбивая первую строку и построчно шагая по методу. По сути, ValidateChildren возвращает false, как и ожидалось, и весь блок if, включая this.Close(), пропускается. Тем не менее, если я перейду весь путь к основанию метода, а затем выйду из него, я снова окажусь на линии frmSettingsForm.ShowDialog(), и форма магически закроется.

Кнопка "Apply" устанавливается как AcceptButton формы. Интересно, неявно ли подключен обработчик к событию кнопки Click, чтобы автоматически закрывать форму при нажатии кнопки. Это не должно звучать логично, особенно если учесть, что нет способа отменить событие Click, но это единственное объяснение, которое я могу придумать. Чтобы проверить эту теорию, я попытался сбросить AcceptButton в конструкторе, но моя форма все еще закрывается, когда данные неверны.

Что закрывает мою форму и как мне ее остановить?

[1]: Если кому-то еще не удается найти его, это свойство формы, а не свойство каждого отдельного элемента управления (как я и ожидал).

Ответы [ 2 ]

9 голосов
/ 29 октября 2010

У вас есть DialogResult из набора Button? Если это так, когда вы нажимаете Button, DialogResult из Form будет установлено на это значение, и модальное значение Form закроется. Чтобы предотвратить это, в случае сбоя проверки в вашем обработчике Click установите Form s DialogResult на DialogResult.None.

0 голосов
/ 27 января 2016

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

  If (DialogResult != Windows.Forms.DialogResult.Cancel )
            e.Cancel = True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...