可观察的收集和inotifypropertychanged

时间:2015-06-11 07:34:11

标签: wpf

当提升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
       }
   }

1 个答案:

答案 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将保持同步。