2009-12-10 1 views
36

Я использую C#. У меня есть форма Windows с полем редактирования и кнопкой «Отмена». В поле редактирования есть код для проверки события. Код выполняется каждый раз, когда поле редактирования теряет фокус. Когда я нажимаю кнопку «Отмена», я просто хочу закрыть форму. Я не хочу, чтобы какая-либо проверка для окна редактирования была выполнена. Как это можно сделать?Как пропустить Подтверждение после нажатия кнопки Отмена формы

Вот важная деталь: если проверка не пройдена, то

  e.Cancel = true; 

предотвращает оставляя контроль.

Но когда пользователь нажимает кнопку «Отмена», форма должна быть закрыта независимо от того, что. как это можно реализовать?

+1

вы ничего сделать, чтобы кнопка «Отмена» предотвратит выполнение кода проверки, когда ваше текстовое поле теряет фокус. – Stewbob

ответ

15

Установить CausesValidation свойство кнопки Отмена до false.

1

Удовлетворительное использование имущества Control.CausesValidation поможет вам достичь того, чего вы хотите.

39

Если проверка выполняется, когда поле редактирования теряет фокус, ничего о кнопке отмены не остановится, чтобы это произошло.

Однако, если сбой проверки не позволяет кнопке отмены выполнить свою задачу, установите для CausesValidation свойство кнопки false.

Reference: Button.CausesValidation property

+0

Не знаете, почему кто-то проголосовал за это. Для приложения winforms это правда. Остальные три ответа неверны. – Stewbob

+0

Это был не я: D –

+1

@ DanielSchaffer: Я не уверен, насколько я понимаю «однако» - правильно. Как я могу предотвратить проверку правильности, когда пользователь нажимает кнопку отмены? Проверка запускает окно сообщений, которое всегда отображается, даже если пользователь хочет отменить редактирование/добавление объекта, потому что проверка происходит до нажатия кнопки. Я даже пытался установить 'CausesValidation = false' из' MouseEnter' из 'BtnCancel' (также не работал). –

27

Очевидно CausesValidation свойство кнопки должен быть установлен в ложь, а затем проверочное событие никогда не произойдет на его щелчком мыши. Но это может завершиться неудачно, если родительский элемент управления кнопки имеет свой CausesValidation Свойство, установленное в true. В большинстве случаев разработчики пропускают/забывают изменить свойство управления контейнером (например, управление панелью) CausesValidation. Установите для этого также значение False. И это должно сделать трюк.

+4

Microsoft должна установить значение 'CausesValidation' по умолчанию для' False' для контейнеров, так как они в любом случае не будут фокусироваться сами по себе. –

+0

Если у меня есть вложенные контейнеры, мне нужно установить его на «False» полностью для всех контейнеров или только для непосредственного родителя моей кнопки? – dotNET

+0

Вот опять через несколько месяцев :). И я понял это позже. Вам не нужно устанавливать его полностью для всех родительских контейнеров. Достаточно установить непосредственный родитель. – dotNET

2

Setting CausesValidation to false - ключ, однако этого недостаточно. Если родительские кнопки имеют значение CausesValidation равным true, событие проверки будет вызвано. В одном из моих случаев у меня была кнопка отмены на панели на форме, поэтому мне пришлось установить CausesValidation = false на панели, а также на форму. В конце концов, я сделал это программно, как это было проще, чем идти через все формы ...

Control control = cancelButton; 

while(control != null) 
{ 
    control.CausesValidation = false; 
    control = control.Parent; 
} 
19

У меня были проблемы с получением мою форму, чтобы закрыть, так как проверка определенных элементов управления было остановить его. Я установил control.CausesValidation = false для кнопки отмены и всех родителей кнопки отмены. Но все еще были проблемы.

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

Это было зафиксировано следующее в случае отмены нажатия кнопки:

private void btnCancel_Click(object sender, EventArgs e) 
{ 
    // Stop the validation of any controls so the form can close. 
    AutoValidate = AutoValidate.Disable; 
    Close(); 
} 
+2

+1 для простоты. – Randy

0

В дополнении к ответу Даниэля Шеффера: если проверка происходит, когда поле редактирования теряет фокус, вы можете forbid the button to activate обойти местный валидация и выход в любом случае.

public class UnselectableButton : Button 
{ 
    public UnselectableButton() 
    { 
     this.SetStyle(ControlStyles.Selectable, false); 
    } 
} 

или если вы используете DevExpress:

this.simpleButtonCancel.AllowFocus = false; 

Заметьте, что делать это изменит опыт клавиатуры: вкладка будет сосредоточено больше на кнопку отмены.

3

Ни один из этих ответов не полностью выполнил эту работу, но последний ответ от this thread. В принципе, вам нужно:

  1. Застраховать, что кнопка Отмена (если таковые имеются) имеет .CausesValidation установлен в ложном
  2. Override этот виртуальный метод.

    protected override bool ProcessDialogKey(Keys keyData) { 
        if (keyData == Keys.Escape) { 
         this.AutoValidate = AutoValidate.Disable; 
         CancelButton.PerformClick(); 
         this.AutoValidate = AutoValidate.Inherit; 
         return true; 
        } 
        return base.ProcessDialogKey(keyData); 
    } 
    

Я на самом деле не ответить на этот вопрос, просто указывая на двух парней, которые на самом деле.

0

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

// The flag 
    private bool _isClosing = false; 

    // Action that avoids validation 
    protected override void OnClosing(CancelEventArgs e) { 
     _isClosing = true; 
     base.OnClosing(e); 
    } 

    // Validated event handler 
    private void txtControlToValidate_Validated(object sender, EventArgs e) {   
     _isClosing = false; 
     var worker = new BackgroundWorker(); 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerAsync(); 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
    } 

    // Do validation on complete so you'll remain on same thread 
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
     if (!_isClosing) 
      DoValidationHere(); 
    } 

    // Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine. 
    void worker_DoWork(object sender, DoWorkEventArgs e) { 
     Thread.Sleep(100); 
    } 
-1

Эта работа для меня.

private void btnCancelar_MouseMove(object sender, MouseEventArgs e) 
{ 
    foreach (Control item in Form.ActiveForm.Controls) 
    { 
     item.CausesValidation = false; 
    } 
} 
+3

Почему и как это работает для вас? – Unheilig

0

Чуть выше код проверки на редактирование окнеДобавление:

if (btnCancel.focused) 
    { 
    return; 
    } 

Это должно сделать это.

+0

Это не делает это для меня. –

0

В моем случае, в форме я установить свойство AutoValidate в EnableAllowFocusChange

0

С помощью Visual Studio Wizzard вы можете сделать это так:

enter image description here