按事件处理启用按钮

时间:2013-04-23 18:29:34

标签: c# winforms event-handling

有一个标签页,其中包含2个面板,一个数据网格视图和一个“清除”按钮。面板中只有文本框,网格未绑定。数据输入由用户提供。默认情况下禁用clear btn。我的要求是,如果任何文本框不为空或网格中有多于一行,则启用。此代码无效。请帮忙。

public Form1()
 {
   InitializeComponent();
   foreach (Control c in InvoiceTab.Controls)
    {
      if (c is DataGridView)
       {
         DataGridView dgv = c as DataGridView;
         if (dgv.RowCount > 1)
          {
            EnableClearBtnBool = true;
            btnClear.Enabled = true;
            break;
          }
         else
          {
            EnableClearBtnBool = false;
            btnClear.Enabled = false;
            break;
          }
       }
    }
    foreach (Control c1 in panel1.Controls)
     {
       if (c1 is TextBox)
        {
          if (c1.Text != "")
            {
              EnableClearBtnBool = true;
              c1.TextChanged -= EnableClearBtn;
              c1.TextChanged += EnableClearBtn;
              break;
            }
          else
             EnableClearBtnBool = false;
        }                  
     }
     foreach (Control c2 in panel2.Controls)
      {
        if (c2 is TextBox)
         {
           if (c2.Text != "")
            {
              EnableClearBtnBool = true;
              c2.TextChanged -= EnableClearBtn;
              c2.TextChanged += EnableClearBtn;
              break;
            }
           else
            EnableClearBtnBool = false;
         }
      }      
 }
bool EnableClearBtnBool = false;
private void EnableClearBtn(object sender, EventArgs e)
    {
        if (EnableClearBtnBool == true)
            btnClear.Enabled = true;
        else
            btnClear.Enabled = false;
    }

1 个答案:

答案 0 :(得分:1)

该代码几乎肯定不起作用,因为它的位置首先是最重要的。但是,我们也应该做出一些根本性的改变。首先,我们需要在可以经常调用的方法中使用此代码:

private void RefreshClearButton()
{
    btnClear.Enabled = textBox1.Text.Length > 0 ||
        textBox2.Text.Length > 0 || ...
        dataGridView.RowCount > 1;
}

但是,我们还需要利用所有文本框上的TextChanged事件:

private void textBox_TextChanged(object sender, EventArgs e)
{
    RefreshClearButton();
}

因此您需要将所有这些挂钩到此事件处理程序。现在,我们还需要在DataGridViewRowsAddedRowsRemoved上使用另外两个事件:

private void dataGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    RefreshClearButton();
}

private void dataGridView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
    RefreshClearButton();
}

所以现在每次发生变化时都会通知我们。如果您必须遍历面板而不是沿途命名每个文本框,那么您可能希望执行以下操作:

private bool HasTextBeenEntered(ControlCollection controls)
{
    foreach (var c in controls)
    {
        if (c is TextBox && ((TextBox)c).Text.Length > 0) { return true; }
        else if (c is Control && HasTextBeenEntered(((Control)c).Controls)) { return true; }
    }

    return false;
}

会略微改变RefreshClearButton方法:

private void RefreshClearButton()
{
    btnClear.Enabled = HasTextBeenEntered(this.Controls) || dataGridView.RowCount > 1;
}

免责声明: 这些代码都没有被编译,所以如果你不得不调整它,不要感到惊讶,但它会让你超过90%的方式