将一个对象分配给另一个对象不会引发 WPF 中的 PropertyChanged 事件

问题描述 投票:0回答:1

我尝试在一个非常简单(且有效)的项目中隔离我的问题。假设我有一个包含 2 个字段的简单模型,并且我已经配置了其属性和

PropertyChanged
事件。这是我的模型的简化实现,请注意最后一个方法只是从列表中获取一个新的客户端对象并返回它:

public class Clients : INotifyPropertyChanged
{
    private long _Id = 0;

    public long Id 
    {
        get { return this._Id; } 
        set { 
            this._Id = value;
            RaisePropertyChanged("Id");
        } 
    }

    private String _Name = string.Empty;

    public String Name 
    {
        get { return this._Name; }
        set { 
            if (value is null) 
                this._Name = string.Empty;
            else
                this._Name = value;
            RaisePropertyChanged("Name");
        } 
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    internal void RaisePropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    // Let's say this is a populated list with 100 clients with different ids and names
    public static List<Clients> clients = new List<Clients>();
    // ...method for loading the list with DB data

    public static Clients? LoadClient(long id)
    {
        return clients.FirstOrDefault(x => x.Id == id);
    }
}

我有一个简单的

.xaml
文件来显示一个客户端数据(id 和名称)。每个 UI 控件都与客户端属性和更新触发器绑定。我还有 2 个已配置的按钮,可以更改客户端值:

<TextBox x:Name="txtClientId" Text="{Binding Id, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<TextBox x:Name="txtClientName" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<Button Name="btnNext" Click="btnNext_Click">Next</Button>
<Button Name="btnRandom" Click="btnRandom_Click">Random</Button>

现在让我们看一下我的

.xaml.cs
代码。这是两个按钮的初始化和代码:其中一个按钮直接修改
DataContext
对象中的客户端属性,另一个只是为
DataContext
客户端分配一个新的客户端对象:

public partial class ClientsPage : Page
{
    private Models.Clients? client = null;

    public ClientsPage()
    {
        InitializeComponent();

        // Load all clients data in Models.Clients.clients list...
        client = new Models.Clients();

        DataContext = client;
    }
    
    private void btnNext_Click(object sender, RoutedEventArgs e)
    {
        client = Models.Clients.LoadClient(client.Id + 1);
    }

    private void btnRandom_Click(object sender, RoutedEventArgs e)
    {
        Random random = new Random();
        client.Id = random.Next(999);
        client.Name = "RANDOM";
    }
}
  • 当我设置 DataContext 时,数据在 UI 中正确显示 -> OK
  • 当我直接在客户端对象的属性中进行更改时,更改会正确反映在 UI 中 -> 确定
  • 但是...当我加载一个新的客户端对象并将其分配给设置为
    DataContext
    的变量时,UI 不会更改,因为未引发
    PropertyChanged
    事件。

当然这种情况可以通过赋值属性值来解决,而不是直接赋值一个新对象:

private void btnNext_Click(object sender, RoutedEventArgs e)
{
    Models.Clients newClient = Models.Clients.LoadClient(client.Id + 1);

    this.client.Id = newClient.Id;
    this.client.Name = newClient.Name;
}

但是在实际项目中,有很多模型和方法可以加载/修改具有很多字段的对象,这是非常乏味的。我正在寻找一种简单/可扩展的方法,以便在将新对象分配给

PropertyChanged
变量时触发
DataContext
事件。如果您需要我的代码的更多详细信息或有任何问题,我很乐意询问。

c# wpf data-binding inotifypropertychanged datacontext
1个回答
0
投票

对象的新实例已创建,但尚未分配给 DataContext。 需要分配给 DataContext。 正确的代码是:

private void btnNext_Click(object sender, RoutedEventArgs e)
    {
        client = Models.Clients.LoadClient(client.Id + 1);
        DataContext = client; 
    }
© www.soinside.com 2019 - 2024. All rights reserved.