c# - WPF - 触发包含在普通属性与 ObservableCollection 属性中的字段的更改
问题描述
在下面的代码示例中,Person 类型的属性与 ObesrvableCollection 类型的属性发生了不同的行为。在这两种情况下,TextBox 都必须编辑 Person.Name 字段。对于这两种情况,TextBlock 都用于在字段上显示更新的值。在 ObservableCollection 的情况下,TextBlock 在 TextBox 上完成编辑后,在“淡出焦点”事件之后更新。在普通属性的情况下,当 TextBox 中的值发生变化时,TextBlock 不会更新,从而淡出焦点。有什么区别?在 ObservableColletion 的情况下,字段值得到更新,幕后发生了什么?
Xaml 视图:
<UserControl ...>
<StackPanel>
<ListBox ItemsSource="{Binding People}" Height="100">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="{Binding People[0].Name}"/>
<TextBox Text="{Binding Mike.Name}"/>
<TextBlock Text="{Binding Mike.Name}"/>
</StackPanel>
</UserControl>
视图模型:
class MainViewModel : BindableBase
{
private Person _mike;
public Person Mike
{
get { return _mike; }
set { SetProperty(ref _mike, value); }
}
public ObservableCollection<Person> People { get; set; } = new ObservableCollection<Person>();
public MainViewModel()
{
People.Add(new Person("Lisa"));
People.Add(new Person("Chris"));
People.Add(new Person("Orlando"));
}
}
人物类:
class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
}
编辑:
我在我的代码中发现了这个问题。就是属性 Mike 从来没有被赋值为 person 类型的值。因此它不会在 TextBlock 中更新。但我的问题仍然存在:为什么 TextBlock 会更新,即使 person 的 Name 属性没有实现 INotifyChanged 机制?
class MainViewModel : BindableBase
{
private Person _mike = new Person("Mike");
public Person Mike
{
get { return _mike; }
set { SetProperty(ref _mike, value); }
}
public ObservableCollection<Person> People { get; set; } = new ObservableCollection<Person>();
public MainViewModel()
{
People.Add(new Person("Lisa"));
People.Add(new Person("Chris"));
People.Add(new Person("Orlando"));
}
}
解决方案
Person 需要实现BindableBase
(假设为 implements INotifyPropertyChanged
),您需要Name
像这样设置属性:
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
目的是在添加、移动或删除ObservableCollection
项目时发出通知;它不跟踪项目的属性。
推荐阅读
- c - 如何使用 cloudamqp 以 C 语言对 paho mqtt 订阅者客户端进行身份验证?
- actions-on-google - 谷歌智能家居中的令牌交换请求出错
- python - 如何将持续时间格式转换为秒?
- scala - Scala - 在组中具有单个值的 KeyValueGroupedDataset 上的 reduceGroups
- openxlsx - Apache POI 4.1 - 新的 XSSFWorkbook 导致 POIXMLException:目前不支持严格的 OOXML
- amazon-web-services - 无法使用 Lambda 生成的 STS 凭证连接到 IoT 端点
- scala - 具有不同类型的处理和数据帧的单个读取流到多个写入流
- docker - 在 Redhat 8 上安装 docker-ce
- javascript - 如何在单个变量下为下拉列表设置多个值?
- php - 通过 laravel 5.4 maatwebsite 包导出时,数字未在 ms excel 中转换为印度货币格式