如何检测表单数据的变化?

时间:2015-08-10 13:12:53

标签: c# .net winforms

我有一个包含大量文本框的表单。我试图在窗体中循环控件以检测文本框,组合框在关闭表单之前是否更改但我无法使其工作。

以下是我所指的代码:

 public partial class PatientFiles : Form, ILookup
 {
    bool NeedSaving = false;

    void CheckChanges(Control.ControlCollection cc)
    {
       foreach (Control ctrl in cc)
       {
          MaskedTextBox mtxtBox = ctrl as MaskedTextBox;
          TextBox txtBox = ctrl as TextBox;
          ComboBox cmb = ctrl as ComboBox;

          mtxtBox.TextChanged += new EventHandler(this.TextWasChanged);
          txtBox.TextChanged += new EventHandler(this.TextWasChanged);
          cmb.SelectedIndexChanged += new EventHandler(this.TextWasChanged);
          //CheckChanges(ctrl.Controls);

       }

    }

    //formload
    private void frmPatient_Load(object sender, EventArgs e)
    {
       EnableNavigation();
       //txtEngName.TextChanged += new EventHandler(TextWasChanged);
       CheckChanges(this.Controls);

    }` 

    public void TextWasChanged(object sender, EventArgs e)
   {
       NeedSaving = true;
   }`

   private void PatientFiles_FormClosing(object sender, FormClosingEventArgs e)
   {
       //NeedSaving();
       // Disable Navigation On Form closing
       if (NeedSaving)
       {

           DialogResult dt = MessageBox.Show("Save Changes", "information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
           if (dt == DialogResult.Yes)
           {
               SaveData();
               //DisableNavigation();
           }

           else if (dt == DialogResult.No)
           {

               DisableNavigation();
               NeedSaving = false;
               this.Close();
           }
           else if (dt == DialogResult.Cancel)
               e.Cancel = true;
       }

   }
}

3 个答案:

答案 0 :(得分:0)

我认为CheckChanges不正确。你应该检查铸造控件的无效性

void CheckChanges(Control.ControlCollection cc)
{
    foreach (Control ctrl in cc)
    {
        MaskedTextBox mtxtBox = ctrl as MaskedTextBox;
        if (mtxtBox != null)
            mtxtBox.TextChanged += new EventHandler(this.TextWasChanged);

        TextBox txtBox = ctrl as TextBox;
        if (txtBox != null)
            txtBox.TextChanged += new EventHandler(this.TextWasChanged);

        ComboBox cmb = ctrl as ComboBox;
        if (cmb != null)
            cmb.SelectedIndexChanged += new EventHandler(this.TextWasChanged);
        //CheckChanges(ctrl.Controls);
    }
}

答案 1 :(得分:0)

什么不起作用?

我看到如果有人将文本更改回原始值,则您的属性NeedSaving仍为真。

为什么不使用每个控件的Tag属性来记住原始值,并在当前值与原始值不同时检查退出。优点:适用于控件集合中的每个控件,而不仅仅是文本框,掩码文本框等。

private void frmPatient_Load(object sender, EventArgs e)
{
   var myControls = cc.Where(c => c is MaskedTextBox || c is TextBox || ...
   foreach (var control in myControls)
   {
       control.Tag = cc.Text;
   }
}

private void PatientFiles_FormClosing(object sender, FormClosingEventArgs e)
{
    bool anythingChanged = cc
        .Where( (c => c is MaskedTextBox || c is TextBox || ...) 
                  && (String.Equals(control.Text, control.Tag.ToString(), ...)
        .Any();
}

只要集合中的第一个元素有更改的文本,就会停止。

缺点:您无法直观地反馈任何已更改的内容。对于该使用事件TextChanged。

答案 2 :(得分:0)

这样可以正常工作,但形成负载开始缓慢

foreach (Control ctrl in cc)
        {
            MaskedTextBox mtxtBox = ctrl as MaskedTextBox;
            if (mtxtBox != null)
                mtxtBox.TextChanged += TextWasChanged;

            TextBox txtBox = ctrl as TextBox;
            if (txtBox != null)
                txtBox.TextChanged += TextWasChanged;

            ComboBox cmb = ctrl as ComboBox;
            if (cmb != null)
                cmb.SelectedIndexChanged += TextWasChanged;
            CheckChanges(ctrl.Controls);
        }