使用依赖项属性默认值作为绑定源

时间:2015-07-27 16:56:16

标签: silverlight data-binding viewmodel dependency-properties

必须使用传统的silverlight应用程序,我遇到了一段奇怪的代码。 viewmodel具有List依赖项属性作为网格的绑定源。此DP具有默认值,即应用程序中全局使用的其他List。这用于在应用程序的不同部分之间轻松共享实体数据。

DependencyProperty MyEntitiesProperty = DependencyProperty.Register("MyEntities", typeof(List<Entity>), typeof(...), new PropertyMetadata(Global.Entities));

现在,当列表发生更改时(在用户操作上),将从数据库重新填充全局列表,但不会显式设置MyEntities。这不起作用:网格(绑定目标)永远不会改变。所以这是一个错误的解决方案。

我推测所有这一切背后的想法可能如下:如果你有一个给定值的DP而你从未为它设置一个本地值,那么DP的有效值将是默认值。如果更改了“基础”默认值,则更改将反映在有效值中。

如果它有效,那么这是一种在独立视图模型之间共享数据的好方法,而不会摆弄属性变化事件等。

这里有什么问题?对于DP如何工作或者想法是否正常以及错过了一些实施细节,这是一个很大的误解吗?

如果不清楚,请发表评论。

1 个答案:

答案 0 :(得分:1)

那么,考虑到你的评论,这是对DP如何运作的一个很大的误解。让我解释一下:

将全局已知列表设置为 MyEntities 的默认值可能不是我推荐的模式,但在技术上没有错误,可以共享列表。 MyEntities 现在拥有对此列表的引用。

如果现在用新列表实例替换全局列表,则旧实例不会停止存在。您的财产 MyEntities 仍然保留对旧列表的引用。 DP的值仅在通过Binding绑定到与INotifyPropertyChanged机制或另一个DP连接的普通属性时自动更新。

设置默认值既不是通过Binding发送到普通属性,也不是通过Binding发送到另一个DP,它只是一个普通的旧对象引用。

我可以想出几种方法来纠正这种情况:

第一个解决方案

如果全局列表实现INotifyCollectionChanged(例如ObservableCollectionDependencyObjectCollection),您可以 - 而不是创建新的列表实例 - 只需从列表中删除旧项并添加新项项目。引用该列表的视图会在收到相关的CollectionChanged事件后立即执行更新。

第二个解决方案

确保Global.Entities列表可用且始终是根视图的INotifyPropertyChanged上的公共属性(与DataContext相连)。现在,当您希望在UI树内部的某个位置连接到此Global.Entities列表时,您可以将其绑定到根视图的DataContext&#39;公共清单属性。

<MyRootView>
    ... nested views spread across multiple files ...
    <MyNestedEntitiesListDisplay
        MyEntities="{Binding
            Path=DataConext.GlobalEntities,
            RelativeSource={RelativeSource AncestorType=MyRootView}}"/>