【问题标题】:ObservableCollection as DependencyPropertyObservableCollection 作为 DependencyProperty
【发布时间】:2011-08-12 13:04:27
【问题描述】:

我正在创建一个应用程序,其中应截获和翻译对象列表,然后再将其显示在一组控件上。为此,我创建了 ObservableCollection 类型的 DependencyProperty(BackupEntry 是定义有关数据库的信息的自定义类)。我想要发生的是控件将绑定到 MVVM 中的 ObservableCollection。此集合可用于初始加载控件。然后,当通过控制接口添加条目时,应将其添加到定义为 DependencyProperty 的内部 ObservableCollection 并显示在 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 永远不会被调用,并且新项目不会显示在我的控件中的集合中。我在这里完全偏离轨道了吗?我需要做些什么才能使其正常工作?

【问题讨论】:

  • 上面的代码是你的 ViewModel 吗?如果是这样,你为什么使用依赖对象而不是属性
  • 不,上面的代码是我控制的代码隐藏。输入到列表中的数据与用于显示它的控件之间没有直接关联。 DependencyObject 旨在公开列表,以便可以绑定它并将数据传入和传出控件。

标签: wpf data-binding observablecollection


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    集合更改事件仅订阅您在 ExplorerWindow 构造函数中设置的 BackupItems 的默认值。然后,您将默认值替换为您未订阅的视图模型中的集合。每次设置属性时,您都需要订阅 collectionchanged。您可以使用接受 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();
    }
    

    【讨论】:

    • 它不起作用。 DependencyProperty 是静态的,但 OnBackupItemsChanged 不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2014-05-03
    • 2011-07-25
    • 1970-01-01
    相关资源
    最近更新 更多