如何使用 lambda 表达式更新 属性?
How to use a lambda expression to update a property?
我有以下 class:
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
表单上的文本框控件通过 BindingSource
绑定到此 class 的一个实例,并且数据源在 OnValidated
事件上更新。
但是,当文本框为空时,它所绑定的 属性 不会更新(再次显示之前的值):
因此,在控件的 OnValidating
事件中,我添加了以下内容:
int value;
bool ok = int.TryParse(((TextBox)sender).Text, out value);
if (!ok)
{
myClassInstance.Field1 = null;
}
问题:
当 TextBox
的值为空时,以上是 BindingSource
的正常行为吗?
是否可以有一个我可以在我的 OnValidating
事件中调用的通用方法。类似于:
OnValidatingMethod((TextBox)sender, x => x.Field1);
上面这行代码显然是行不通的,因为没有引用对象实例。但我想知道这样的事情是否可能?也许是 class:
的扩展
myClassInstance.SetProperty(((TextBox)sender).Text, x => x.Field1);
数据绑定的整个思想就是从源中抽象出目标。如果您创建了这样的事件处理程序,那么抽象就结束了。
您看到的当然不正常,但这是为 "backward compatibility" 保留的非常古老的错误的结果。很久以前就通过向 Binding class 添加额外的属性来修复它,但同样为了向后兼容,默认值设置为模仿旧行为。
要使其按预期工作,您需要设置的属性是 FormattingEnabled
to true
, and NullValue
到 ""
。我通常使用允许指定所有信息的 DataBindings.Add
或 Binding
构造函数重载之一,如下所示:
textBox.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
这是一个完整的演示:
using System;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var textBox1 = new TextBox { Parent = form, Left = 16, Top = 16 };
var textBox2 = new TextBox { Parent = form, Left = 16, Top = textBox1.Bottom + 16 };
var bs = new BindingSource { DataSource = typeof(MyClass) };
textBox1.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
textBox2.DataBindings.Add("Text", bs, "Field2", true, DataSourceUpdateMode.OnValidation, "");
bs.DataSource = new MyClass { Field1 = 1, Field2 = 2 };
Application.Run(form);
}
}
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
}
最后,如果你真的想参与解析部分,你应该将处理程序附加到Binding.Parse
事件。
我有以下 class:
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
表单上的文本框控件通过 BindingSource
绑定到此 class 的一个实例,并且数据源在 OnValidated
事件上更新。
但是,当文本框为空时,它所绑定的 属性 不会更新(再次显示之前的值):
因此,在控件的 OnValidating
事件中,我添加了以下内容:
int value;
bool ok = int.TryParse(((TextBox)sender).Text, out value);
if (!ok)
{
myClassInstance.Field1 = null;
}
问题:
当
TextBox
的值为空时,以上是BindingSource
的正常行为吗?是否可以有一个我可以在我的
OnValidating
事件中调用的通用方法。类似于:OnValidatingMethod((TextBox)sender, x => x.Field1);
上面这行代码显然是行不通的,因为没有引用对象实例。但我想知道这样的事情是否可能?也许是 class:
的扩展myClassInstance.SetProperty(((TextBox)sender).Text, x => x.Field1);
数据绑定的整个思想就是从源中抽象出目标。如果您创建了这样的事件处理程序,那么抽象就结束了。
您看到的当然不正常,但这是为 "backward compatibility" 保留的非常古老的错误的结果。很久以前就通过向 Binding class 添加额外的属性来修复它,但同样为了向后兼容,默认值设置为模仿旧行为。
要使其按预期工作,您需要设置的属性是 FormattingEnabled
to true
, and NullValue
到 ""
。我通常使用允许指定所有信息的 DataBindings.Add
或 Binding
构造函数重载之一,如下所示:
textBox.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
这是一个完整的演示:
using System;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var textBox1 = new TextBox { Parent = form, Left = 16, Top = 16 };
var textBox2 = new TextBox { Parent = form, Left = 16, Top = textBox1.Bottom + 16 };
var bs = new BindingSource { DataSource = typeof(MyClass) };
textBox1.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
textBox2.DataBindings.Add("Text", bs, "Field2", true, DataSourceUpdateMode.OnValidation, "");
bs.DataSource = new MyClass { Field1 = 1, Field2 = 2 };
Application.Run(form);
}
}
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
}
最后,如果你真的想参与解析部分,你应该将处理程序附加到Binding.Parse
事件。