【问题标题】:How to use a lambda expression to update a property?如何使用 lambda 表达式更新属性?
【发布时间】:2016-04-22 07:36:48
【问题描述】:

我有以下课程:

public class MyClass
{
    public int? Field1 { get; set; }
    public int? Field2 { get; set; }
}

表单上的文本框控件通过BindingSource绑定到此类的一个实例,并且数据源在OnValidated事件上更新。

但是,当文本框为空时,它绑定的属性没有被更新(再次显示之前的值):

因此,在控件的 OnValidating 事件中,我添加了以下内容:

int value;
bool ok = int.TryParse(((TextBox)sender).Text, out value);
if (!ok)
{
    myClassInstance.Field1 = null;
}

问题:

  1. 以上是TextBox的值为空时BindingSource的正常行为吗?

  2. 是否有可以在我的OnValidating 事件中调用的通用方法。比如:

    OnValidatingMethod((TextBox)sender, x => x.Field1);
    

上面这行代码显然行不通,因为没有引用对象实例。但我想知道这样的事情是否可能?也许是类的扩展:

myClassInstance.SetProperty(((TextBox)sender).Text, x => x.Field1);

【问题讨论】:

    标签: c# data-binding lambda expression-trees bindingsource


    【解决方案1】:

    数据绑定的整个想法是从源中抽象出目标。如果您创建这样的事件处理程序,抽象就结束了。

    你看到的当然不是正常的,而是为了“向后兼容”而保留的一个非常古老的错误的结果。很久以前就通过向Binding 类添加其他属性来修复它,但再次为了向后兼容,默认值被设置为模仿旧行为。

    您需要设置的属性是FormattingEnabledtrue,以及NullValue""。我通常使用允许指定所有信息的DataBindings.AddBinding 构造函数重载之一,如下所示:

    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事件。

    【讨论】:

    • 感谢您的解释,像往常一样,很好的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    相关资源
    最近更新 更多