C# WInForms 文本框数据绑定刷新 TetxtBox.Text 如果绑定属性更改

本文关键字:绑定 如果 属性 Text TetxtBox 文本 WInForms 数据绑定 刷新 | 更新日期: 2023-09-27 18:25:12

class Class1
{
   public string val {get;set;}
}
Class1 cl;
private void Form1_Load(object sender, EventArgs e)
{
cl = new Class1();
            textBox1.DataBindings.Add("Text",cl,"val",false,DataSourceUpdateMode.OnPropertyChanged,);
            textBox2.DataBindings.Add("Text", cl, "val", false, DataSourceUpdateMode.OnPropertyChanged);
        }    

        private void button1_Click(object sender, EventArgs e)
        {
            cl.val += "11";
        }

我在文本框 1 中更改值,在文本框 2 的值也会立即更改。
如果我单击按钮,绑定值 cl.val 从代码更改,但两个文本框值保持不变。
如果 cl.val 从代码更改,如何刷新文本框表单上的数据?

PS:如果在行
之后cl.val += "11"; -加
文本框1.文本 = cl.val;
然后在两个文本框
处值刷新为什么?

C# WInForms 文本框数据绑定刷新 TetxtBox.Text 如果绑定属性更改

为了使数据绑定在代码更改数据源属性时起作用,数据源(在您的情况下Class1(必须提供某种属性更改通知。可能的选择是称为PropertyNameChanged的事件,其中PropertyName是应用更改通知的属性的名称,或者更通用的方法是实现 INotifyPropertyChanged 接口。

下面是使用第二种方法的示例。由于不能再使用 C# auto 属性,因此人们通常会创建一个基类来减少所需的重复样板代码,如下所示

public abstract class BindableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected static bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

然后按如下方式使用它

class Class1 : BindableObject
{
    private string _val;
    public string val
    {
        get { return _val; }
        set { SetProperty(ref _val, value); }
    }
}

完成此操作后,一切都将按预期工作。

如果如你所说,你的类是由 EF 自动生成的,则需要创建一个用于 UI 数据绑定的包装类(通常称为 ViewModel(。通常,DTO、实体等类不能在 UI 中直接使用。

更新 虽然以上所有内容都是正确的方法,但为了完整起见,这里有一个快速而肮脏的方法。

辅助功能:

public static class DataBindingUtils
{
    public static void RefreshBindings(this BindingContext context, object dataSource)
    {
        foreach (var binding in context[dataSource].Bindings.Cast<Binding>())
            binding.ReadValue();
    }
}

示例用法:

private void button1_Click(object sender, EventArgs e)
{
    cl.val += "11";
    BindingContext.RefreshBindings(cl);
}

试试这个:

cl.val+="11";
textBox1.ResetBindings();
textBox2.ResetBindings();


更新

事实是,当您更改类值时,您必须通知 UI 基础数据已更改,因此您必须在类中实现 INotifyPropertyChanged。 像这样定义你的类 Class1 并尝试一下:

class Class1:INotifyPropertyChanged
    {
        private string _val;
        public string val
        {
            get
            {
                return this._val;
            }
            set
            {
                if (this._val != value)
                {
                    this._val = value;
                    NotifyPropertyChanged("");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


更新 2

正如Ivan和我所解释的那样,实现INotifyPropertyChanged的方法是实现INotifyPropertyChanged。但是如果你想要一种肮脏的方式,你可以清除数据绑定并再次添加它们,如下所示:

cl.val += "11";
foreach (Control c in this.Controls)
{
       if (c is TextBox)
       {
            c.DataBindings.Clear();
            c.DataBindings.Add("Text", cl, "val", false, DataSourceUpdateMode.OnPropertyChanged);
        }
 }