我尝试在一个非常简单(且有效)的项目中隔离我的问题。假设我有一个包含 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 不会更改,因为未引发 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
事件。如果您需要我的代码的更多详细信息或有任何问题,我很乐意询问。
对象的新实例已创建,但尚未分配给 DataContext。 需要分配给 DataContext。 正确的代码是:
private void btnNext_Click(object sender, RoutedEventArgs e)
{
client = Models.Clients.LoadClient(client.Id + 1);
DataContext = client;
}