当提升CollectionChanged事件时,ObservableCollection是自包含的,因为它实现了INotifyPropertyChanged和INotifyCollectionChanged。所以我认为,我们不需要再次实现INotifyPropertyChanged。
但我已经看到一些例子,其中人们将ObservableCollection定义为属性并在setter中引发属性更改事件。我不明白为什么要再次这样做,或者更好地说明为什么他们在setter中提升属性改变事件(见下面的代码)。正如我们已经知道ObservableCollection在添加时自动引发,更新完成,那么我们不需要再次提升。直接?
请澄清我的疑问。
public class TheViewModel()
{
private ObservableCollection<Camper> _campers;
public ObservableCollection<Camper> Campers
{
get { return _campers; }
set
{
if (Equals(_campers, value)) return;
_campers = value;
RaisePropertyChanged("Campers"); //Or however you implement it
}
}
答案 0 :(得分:0)
如果您将Campers设置为指向新实例,则RaisePropertyChanged将为您完成此任务。否则,您将获得对旧实例的引用,并且View将保持不同步。另一个解决方案是,每次将Campers设置为指向新集合时,再次为您的DataGrid或ListView或您使用的控件设置ItemsSource。
实际上,只要您从集合中添加或删除项目,此功能就可以正常工作。总而言之,当您再次设置
时,差异就在于此Campers = new ObservableCollection<Camper>();
您的RaisePropertyChanged将被触发。
代码更新:
XAML:
<Window x:Class="ObservablePropertyChanged.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<ListView ItemsSource="{Binding items}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Change collection" Click="btnChangeCollection_Click"/>
</StackPanel>
</Grid>
代码背后:
public partial class MainWindow : Window
{
public ObservableCollection<string> items { get; set; }
public MainWindow()
{
InitializeComponent();
items = new ObservableCollection<string>();
items.Add("One");
items.Add("Two");
this.DataContext = this;
}
private void btnChangeCollection_Click(object sender, RoutedEventArgs e)
{
items = new ObservableCollection<string>();
items.Add("Three");
items.Add("Four");
}
}
由于我没有实现INPC界面,并且没有在物品集合的集合上添加PropertyChanged,因此在点击按钮后,您将无法使用项目更新视图&#34; Three&#34;和&#34;四&#34;。
以下是实现此行为的另一种方法:
public ObservableCollection<string> items
{
get { return (ObservableCollection<string>)GetValue(itemsProperty); }
set { SetValue(itemsProperty, value); }
}
// Using a DependencyProperty as the backing store for items. This enables animation, styling, binding, etc...
public static readonly DependencyProperty itemsProperty =
DependencyProperty.Register("items", typeof(ObservableCollection<string>), typeof(MainWindow), new UIPropertyMetadata(null));
使用此依赖项属性,ListView将保持同步。