当我将新对象实例分配给绑定变量时,数据绑定不起作用

pft*_*way 7 .net c# data-binding winforms

我有一个对象,我已使用C#WinForms(目标.NET 4.5.2)绑定到窗体上的控件.我已实现INotifyPropertyChanged,当我修改此对象的属性时,它会按预期更新窗体的控件.但是,当我将此对象的实例更改为新实例时,即使我尝试修改特定属性,它也不会再更新控件.

class User : INotifyPropertyChanged
{
    string _name = "";

    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged("Name"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }

    public User() { }

    public User(string name)
    {
        Name = name;
    }

    public User(User otherUser)
    {
        Name = otherUser.Name;
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的表格上

User currentUser = new User("Example Name");
lblName.DataBindings.Add("Text", currentUser, "Name");
Run Code Online (Sandbox Code Playgroud)

哪个更新得当.我可以使用更改名称currentUser.Name = "Blahblah";,它工作正常.当我试着打电话时currentUser = new User("New Name");,无论我做什么,它都不会再更新.

据我所知,对象的特定实例是控件绑定的对象.我的主要目标是不必手动浏览较大对象的每个属性,并且每次想要更改实例时都手动更改所有内容.

我的问题:有没有办法在不删除绑定到控件的情况下更改对象的实例?

Iva*_*oev 5

为了获得所需的行为,您不应像当前那样直接绑定到具体实例:

lblName.DataBindings.Add("Text", currentUser, "Name");
Run Code Online (Sandbox Code Playgroud)

相反,你需要一些中介。最简单的方法是使用该BindingSource组件来实现此目的。

BindingSource向表单添加一个字段:

private BindingSource dataSource;
Run Code Online (Sandbox Code Playgroud)

然后初始化它并将控件绑定到它一次(通常在表单Load事件中):

dataSource = new BindingSource { DataSource = typeof(User) };
lblName.DataBindings.Add("Text", dataSource, "Name");
// ...
Run Code Online (Sandbox Code Playgroud)

现在,只要您想要绑定到User实例,您只需将其分配给DataSource的属性BindingSource

最初的:

dataSource.DataSource = new User("Example Name");
Run Code Online (Sandbox Code Playgroud)

之后:

dataSource.DataSource = new User("New Name"); 
Run Code Online (Sandbox Code Playgroud)