3

我正在使用 C# Windows Forms (.NET 3.5),并尝试在用户修改 Detail 表单上的任何数据有界列并尝试关闭表单而不保存时实现该功能,系统应该弹出我的消息“保存变化?”。

我知道我总是可以使用TextChanged事件Textbox等,但这需要多个事件编码。我想使用一个特定的事件处理程序来检测与 my 关联的任何字段中的值变化BindingSource

我已经像这样限制了我的列:

textbox1.DataBindings.Add("Text", this.bindingSource1, "dbcolumn_1", true);
4

3 回答 3

1

像这样的东西会起作用吗?

  1. 在表单中定义一个 changedFlag 变量,默认值 = false。

    private changedFlag = false; // form value(s) changed, check it on form close

  2. 将其放入退出按钮的事件处理程序中,或适应表单关闭处理程序:

        if (this.changedFlag && MessageBox.Show("Save your changes before exit?", "Save changes?", MessageBoxButtons.OKCancel) == DialogResult.OK)
        {
            this.Save();
        }
    
  3. 创建一个函数,该函数接受一个控件容器并递归地查看其控件以连接更改处理程序(在步骤 4 中定义)。

    private void AddOnChangeHandlerToInputControls(Control ctrl)
    {
        foreach (Control subctrl in ctrl.Controls)
        {
            if (subctrl is TextBox)
            {
                ((TextBox)subctrl).TextChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is CheckBox)
            {
                ((CheckBox)subctrl).CheckedChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is RadioButton)
            {
                ((RadioButton)subctrl).CheckedChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is ListBox)
            {
                ((ListBox)subctrl).SelectedIndexChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is ComboBox)
            {
                ((ComboBox)subctrl).SelectedIndexChanged += new EventHandler(InputControls_OnChange);
            }
            else
            {
                if (subctrl.Controls.Count > 0)
                {
                    this.AddOnChangeHandlerToInputControls(subctrl);
                }
            }
        }
    }
    
  4. 创建一个设置 changedFlag = true 的通用更改处理函数

    private void InputControls_OnChange(object sender, EventArgs e)
    {
        this.changedFlag = true;
    }
    
  5. 一旦您的控件被构建(不确定您是否正在动态制作它们,但您textbox1在示例中使用了所以我假设不是),从第 3 步调用该函数并传入输入的容器控件。

    AddOnChangeHandlerToInputControls(panelFormContainer);

通过传入表单控件的容器,您可以避免手动连接每个控件的更改处理程序。并且记得修改 Save() 函数来重置changedFlag = false;

于 2012-11-30T19:46:16.633 回答
0

定义 on_closure 事件处理程序; http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onclosing.aspx

在那里启动一个表单,询问他们是否要保存并将其作为对话框打开,以便将焦点强制在该表单上(链接中的示例代码显示了如何执行所有这些操作)。

于 2012-10-31T21:25:29.670 回答
0

nothingIsNecessary 的答案非常接近,但我仍然需要环顾四周才能使其正常工作。

也就是说,问题是

AddOnChangeHandlerToInputControls(panelFormContainer);

应该

AddOnChangeHandlerToInputControls(this);

panelFormContainer 不起作用,我也找不到它的文档。

参考:循环遍历表单上的所有控件,甚至是组框中的控件

我还继续根据需要添加了更多控件类型。我将 MouseCaptureChanged 用于 datePicker,因为复选框有时会触发 ValueChanged,有时不会。¯_(ツ)_/¯

private void AddOnChangeHandlerToInputControls(Control ctrl) 
    {
        foreach (Control subctrl in ctrl.Controls)
        {
            if (subctrl is TextBox)
            {
                ((TextBox)subctrl).TextChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is CheckBox)
            {
                ((CheckBox)subctrl).CheckedChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is RadioButton)
            {
                ((RadioButton)subctrl).CheckedChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is ListBox)
            {
                ((ListBox)subctrl).SelectedIndexChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is ComboBox)
            {
                ((ComboBox)subctrl).SelectedIndexChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is MaskedTextBox)
            {
                ((MaskedTextBox)subctrl).TextChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is DateTimePicker)
            {
                ((DateTimePicker)subctrl).MouseCaptureChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is RichTextBox)
            {
                ((RichTextBox)subctrl).TextChanged += new EventHandler(InputControls_OnChange);
            }
            else if (subctrl is NumericUpDown)
            {
                ((NumericUpDown)subctrl).TextChanged += new EventHandler(InputControls_OnChange);
            }
            else
            {
                if (subctrl.Controls.Count > 0)
                {
                    this.AddOnChangeHandlerToInputControls(subctrl);
                }
            }
        }
    }
于 2018-04-05T00:43:23.803 回答