Почему обработчик события «Проверка» моей кнопки никогда не вызывается?

2

В следующем мини-приложении мне интересно, почему обработчик событий BtnOk_Validating не вызывается. Я ожидал, что нажатие кнопки Ok вызовет обработчик событий.

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

Если это не очевидно, я довольно новичок, когда дело доходит до разработки форм.

using System.ComponentModel;
using System.Windows.Forms;

namespace ConsoleApp
{
    class Program
    {
        static void Main( string[] args )
        {
            Dialog dialog = new Dialog();

            dialog.ShowDialog();
        }
    }

    public class Dialog : Form
    {
        Button m_BtnOk;
        Button m_BtnCancel;

        public Dialog()
        {
            m_BtnOk = new System.Windows.Forms.Button();
            m_BtnCancel = new System.Windows.Forms.Button();

            m_BtnOk.CausesValidation = true;
            m_BtnOk.DialogResult = DialogResult.OK;
            m_BtnOk.Text = "Ok";
            m_BtnOk.Location = new System.Drawing.Point( 0, 0 );
            m_BtnOk.Size = new System.Drawing.Size( 70, 23 );
            m_BtnOk.Validating += new CancelEventHandler( BtnOk_Validating );

            m_BtnCancel.CausesValidation = false;
            m_BtnCancel.DialogResult = DialogResult.Cancel;
            m_BtnCancel.Text = "Cancel";
            m_BtnCancel.Location = new System.Drawing.Point( 0, 30 );
            m_BtnCancel.Size = new System.Drawing.Size( 70, 23 );

            Controls.Add( this.m_BtnOk );
            Controls.Add( this.m_BtnCancel );
        }

        private void BtnOk_Validating( object sender, CancelEventArgs e )
        {
            System.Diagnostics.Debug.Assert( false ); // we never get here
        }
    }
}

Изменить: см. мой последующий question для более полного примера, который работает (в основном).

  • 2
    Winforms достаточно умен, чтобы знать, что вы никогда не подтвердите кнопку;) Добавьте обработчик события Click кнопки, вызовите this.Close ().
  • 0
    Закрытие диалогового окна не является проблемой. В реальном диалоге есть несколько элементов управления текстовым полем. Я хочу использовать обработчик события кнопки Ok, чтобы вызвать каждый из методов обработки события проверки текста. Управление событием клика мне не очень помогает в этом отношении.
Показать ещё 3 комментария
Теги:
winforms
events

1 ответ

6
Лучший ответ

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

Из MSDN

Когда вы меняете фокус с помощью клавиатуры (TAB, SHIFT + TAB и т.д.), вызывая методы Select или SelectNextControl или устанавливая свойство ContainerControl.ActiveControl в текущую форму, события фокуса происходят в в следующем порядке:

   Enter    
   GotFocus    
   Leave    
   Validating    
   Validated    
   LostFocus    

Когда вы меняете фокус с помощью мыши или вызывая метод Фокус, события фокуса происходят в следующем порядке:

   Enter    
   GotFocus    
   LostFocus    
   Leave    
   Validating    
   Validated    

Если для свойства CausesValidation установлено значение false, события Validating and Validated будут отключены.

Обновление. Как упоминает Ханс, вам нужно извлечь подтверждение, которое вы делаете в каждом из проверочных событий, для всех остальных элементов управления в отдельные функции. Затем вы можете создать функцию ValidateAll, чтобы проверить все значения. Если функция возвращает false, то вы не закрываете Form. Если он возвращает true, вы вызываете this.Close(). Таким образом, это может выглядеть так:

// pseudo code
textbox1.Validating += ValidateTx1();
textbox2.Validating += ValidateTx2();
btnOk.Click += OkBtnClicked();

private void OkBtnClicked(...)
{
    if(ValidateAll())
    {
       this.Close();
    }
}

private bool ValidateTx1(...)
{
   DoTx1Validation();
}

private bool ValidateTx2(...)
{
   DoTx2Validation();
}

private bool ValidateAll()
{
   bool is_valid = DoTx1Validation();
   return (is_valid && DoTx2Validation());
}
  • 0
    Я обновил фрагмент кода, чтобы иметь другую кнопку. Перемещение между кнопками с помощью клавиши табуляции по-прежнему не вызывает обработчик событий. Реальный диалог имеет гораздо больше элементов управления, каждый из которых имеет проверяющий обработчик события. Я хотел использовать обработчик события, проверяющий кнопку Ok, чтобы вызвать все остальные обработчики событий, прежде чем закрыть диалоговое окно.
  • 0
    @ Майкл - я обновил ответ. Дайте мне знать, если это больше того, что вы ищете.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню