C# WInForms TextBox DataBinding 如果绑定(bind)属性更改则刷新 TetxtBox.Text

标签 c# winforms

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";
        }

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

PS:如果在行
之后 cl.val += "11"; - 添加
textBox1.Text = cl.val;
然后在两个文本框中刷新值
这是为什么?

最佳答案

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

这是使用第二种方法的示例。由于 C# 自动属性不能再使用,人们通常会创建一个基类来减少这样的重复样板代码

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 自动生成的,那么您需要创建一个包装类(通常称为 ViewModel)来用于 UI 数据绑定(bind)。一般来说,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);
}

关于C# WInForms TextBox DataBinding 如果绑定(bind)属性更改则刷新 TetxtBox.Text,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33996655/

相关文章:

c# - 这是重载方法的坏习惯吗?

c# - 如何访问放置在面板中的控件的值?

c# - C# WinForms 的可编辑数据网格

c# - 将 List<Double> 绑定(bind)到 WinForms-Listbox

TopMost = true 的 WinForms 对话框

c# - 为什么通过 ADO.NET 执行的存储过程花费的时间比 SQL Server Management Studio 长很多倍?

c# - 使用 Office 互操作程序集获取 Word 页眉/页脚中的内容控件

c# - 如何使用 LINQ 比较 List<> 中顺序 "neighbors"的值?

c# - 通过单元格的值设置选定的行datagridview

c# - 如何创建非矩形窗体?