为什么在使用WriteValue更新布尔绑定时会出现格式异常?

时间:2015-06-19 15:46:23

标签: c# data-binding binding .net-3.5

我的表单上有一堆Checkbox,其Checked属性绑定到数据模型上的Boolean属性:

chk1.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty1", false))
chk2.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty2", false))
chk3.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty3", false))

屏幕上的所有复选框都有一个共享事件处理程序,可确保将数据绑定值正确设置为选中的值。

private void AllCheckboxes_CheckedChanged(object sender, EventArgs e)
{
    var chk = ((CheckBox)sender);

    var binding = chk.DataBindings["Checked"];
    if (binding != null)
        binding.WriteValue();
}

在某些情况下,第一次加载此表单和绑定时,我得到一个例外:

  

无法将值格式化为所需类型。

     

at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component,Object value)   在System.Windows.Forms.BindToObject.SetValue(对象值)   在System.Windows.Forms.Binding.PullData(布尔重新格式,布尔力)   在System.Windows.Forms.Binding.WriteValue()

它可以正常处理事件的第一个复选框,但第二个复选框将抛出此异常。

数据源是我的数据模型的接口

public interface IMyDataModel
{
    bool MyBooleanProperty1 { get; set; }
    bool MyBooleanProperty2 { get; set; }
    bool MyBooleanProperty3 { get; set; }
}

我可以通过在事件处理程序中的.WriteValue之前设置断点来验证数据模型本身是否设置正确。我甚至可以在绑定的布尔属性的setter中放置一个断点,并且它也被正确调用。

如果我将绑定的FormattingEnabled属性设置为true,它确实解决了问题。但我想知道为什么我首先必须这样做,因为我将UI对象中的System.Boolean属性绑定到数据源上的bool属性。

为什么我会在这种情况下得到这个例外?

4 个答案:

答案 0 :(得分:1)

如果没有办法重现这个问题,很难肯定会发生什么。

但至少我可以解释为什么设置FormattingEnabled会让异常消失:

http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Binding.cs,853

WriteData使用PullDatareformat = true来调用force = true

从您的调用堆栈中,您似乎必须将其置于此块中:

            // Put the value into the data model
            if (!parseFailed) {
                this.bindToObject.SetValue(parsedValue);
            }

在此之后,除非 FormattingEnabled = true,否则将重新抛出异常。所以在这里设置FormattingEnabled隐藏了问题,因为看起来Binding假设您将处理目前为止发现的任何格式/解析问题。

至于为什么首先抛出异常...我不知道。在这里没有什么是明显的:

http://referencesource.microsoft.com/#system/compmod/system/componentmodel/ReflectPropertyDescriptor.cs,1138

如果您找到一种在没有BindingValue自定义类的情况下添加数据绑定的方法,我很想知道您的问题是否仍然存在。如果你有BindingValue的任何听众,我也很好奇。

答案 1 :(得分:0)

我认为如果没有处理解析/格式会引发异常,这就是formattingEnabled似乎有用的原因。

尝试处理Binding.FormatBinding.Parse事件,以验证它发送(和期望)的类型是否正确。

答案 2 :(得分:0)

这就是我要做的。 该模型应实现INotifyPropertyChanged接口。 从ToolBox中向表单添加BindingSource。将DataSource设置为您的模型。在每个复选框上设置数据绑定。我将使用“高级”窗口并将数据源更新模式设置为OnPropertyChanged。 在这种情况下,您不必为复选框设置任何事件处理程序。

答案 3 :(得分:0)

尝试启用格式如下 -

this.chk1.DataBindings.Add(new System.Windows.Forms.Binding("EditValue", this.bindingSource1, "MyProperty", true));

您还可以浏览以下链接 -

http://msdn.microsoft.com/en-us/library/system.windows.forms.binding.formattingenabled.aspx