ObservableCollection作为DependencyProperty

时间:2011-08-12 13:04:27

标签: wpf data-binding observablecollection

我正在创建一个应用程序,其中应该拦截和翻译对象列表,然后才能在一组控件上显示。为此,我创建了一个ObservableCollection类型的DependencyProperty(BackupEntry是一个定义数据库信息的自定义类)。我想要发生的是控件将绑定到MVVM中的ObservableCollection。此集合可用于初始加载控件。然后,当通过控制接口添加一个条目时,它应该被添加到内部的ObservableCollection中,该内部ObservableCollection被定义为DependencyProperty并且由于它们被绑定而显示在MVVM的集合中。这是我正在使用的代码:

protected ObservableCollection<BackupEntry> _BackupItems = new ObservableCollection<BackupEntry>();

public static readonly DependencyProperty BackupItemsProperty = DependencyProperty.Register("BackupItems", typeof(ObservableCollection<BackupEntry>), typeof(ExplorerWindow));

public ObservableCollection<BackupEntry> BackupItems
{
    get { return (ObservableCollection<BackupEntry>)GetValue(BackupItemsProperty); }
    set { SetValue(BackupItemsProperty, value); }
}

public ExplorerWindow()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ExplorerWindow), new FrameworkPropertyMetadata(typeof(ExplorerWindow)));
    SetValue(BackupItemsProperty, _BackupItems);
    _BackupItems.CollectionChanged += new NotifyCollectionChangedEventHandler(BackupItems_CollectionChanged);
}

void BackupItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    throw new NotImplementedException();
}

在测试应用中:

<my:ExplorerWindow Name="ew" HorizontalAlignment="Left" VerticalAlignment="Top" Width="503" Height="223" BackupItems="{Binding BackupListItems}" />

我在测试应用中在屏幕上创建了一个按钮。单击它时,会将一个项添加到BackupListItems。永远不会调用BackupItems_CollectionChanged,并且我的控件中的新集合不会显示在我的集合中。我完全偏离了这里吗?我需要做些什么来实现这个目标?

2 个答案:

答案 0 :(得分:9)

您应该遵循this question中给出的模式。您需要订阅CollectionChanged处理程序中的PropertyChanged事件,如上面的链接所示。

答案 1 :(得分:-1)

集合更改事件仅订阅您在ExplorerWindow构造函数中设置的BackupItems的默认值。然后,使用viewmodel中的集合替换默认值 - 您尚未订阅该集合。每次设置属性时,您都需要订阅collectionschanged。您可以使用接受PropertyMetadata的DependencyProperty.Register重载,并在属性更改时提供回调。这是一个粗略的草图 - 没有编译它,但应该指向正确的方向。

 public static readonly DependencyProperty BackupItemsProperty = DependencyProperty.Register(
    "BackupItems", 
    typeof(ObservableCollection<BackupEntry>), 
    typeof(ExplorerWindow), 
    OnBackupItemsChanged);

private void OnBackupItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var old = (ObservableCollection<BackupEntry>)e.OldValue;
    if (old != null) 
    {
       old.CollectionChanged -= BackupItems_CollectionChanged;
    }
    ((ObservableCollection<BackupEntry>)e.NewValue).CollectionChanged += BackupItems_CollectionChanged;
}

void BackupItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    throw new NotImplementedException();
}