WinForms dataBinding 触发 2 次 CheckedChanged 事件,使 checkBox 不可点击

Posted

技术标签:

【中文标题】WinForms dataBinding 触发 2 次 CheckedChanged 事件,使 checkBox 不可点击【英文标题】:WinForms dataBinding triggers 2 times CheckedChanged event and makes the checkBox unclickable 【发布时间】:2020-05-28 08:52:35 【问题描述】:

下面的代码来自一个简单的测试应用程序,在表单上只包含一个复选框。

DataTable dt;

public Form1()

    InitializeComponent();

    dt = new DataTable(); 
    dt.Columns.Add("bool", typeof(bool));
    dt.Columns.Add("s", typeof(string));
    dt.Rows.Add(new object[2]  false, "" );
    checkBox1.DataBindings.Add("Checked", dt, "bool", false, DataSourceUpdateMode.OnValidation);
    checkBox1.CheckedChanged += CheckBox_CheckedChanged;


private void CheckBox_CheckedChanged(object sender, EventArgs e)

    dt.Rows[0]["s"] = "test";

这条线dt.Rows[0]["s"] = "test"; 使复选框不可点击。 CheckedChanged 被触发 2 次。响应点击事件后的第一次。第二次被堆栈中显示 CurrencyManager 和 BindingManagerBase.PushData 的外部代码调用。

如果我删除这一行或在计时器中运行它,checkBox 的行为是正常的。

【问题讨论】:

将绑定更改为DataSourceUpdateMode.OnPropertyChanged 【参考方案1】:

将数据源更新模式改为OnPropertyChanged

当数据源更新模式为OnValidation时,当CheckedChanged发生时,该值仍然没有写入数据源,因为没有发生验证。所以数据源还是有之前的校验状态。然后,在您更改数据源上的值后,无论您更新哪个列,数据绑定都会尝试将当前记录的最新值推送到控件。这就是为什么检查的值不会改变并且总是显示当前行的 bool 列的值。

你也可以试试这个,同时保持数据源更新模式为OnValidation

checkBox1.DataBindings["Checked"].WriteValue();
dt.Rows[0]["s"] = "test";

这与将更新模式设置为OnPropertyChanged基本相同。

【讨论】:

无论您更新哪一列,数据绑定都会尝试将当前记录的最新值推送到控件 - 这是在 Winforms 中尝试使用 MVVM 方法时的关键知识

以上是关于WinForms dataBinding 触发 2 次 CheckedChanged 事件,使 checkBox 不可点击的主要内容,如果未能解决你的问题,请参考以下文章

winForms + DataGridView 绑定到 List<T>

C# WinForms DragEnter 从不触发

Winforms MonthCalendar DateSelected 事件不会在第一次单击 MaxDate 时触发

当鼠标仍然按下时,如何防止在 Winforms Listview 中立即触发 MouseUp 事件?

Winforms:没有绑定的快捷键文本

Android MVI 架构学习