对于 View / View 模型,我有以下(浓缩的)silverlight xaml:
<UserControl x:Class=MyView>
<UserControl.Resources>
<MyViewModel x:Name="MyViewModel"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>
希望这对大家来说很熟悉。
但是,我想创建同一个 View 用户控件的 2 个实例,但是要向 View 模型传递一个参数,以允许我基于传递给 View 模型的属性具有稍微不同的 View 模型数据。就像是:
<UserControl x:Class=MyView>
<UserControl.Resources>
<MyViewModel x:Name="MyViewModel" Filter="Some value set at a higher level"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource MyViewModel}}">
<UserControl>
问题是我无法在用户控件中硬编码 Filter 参数,而是需要将其设置为更高级别。有没有办法通过绑定(bind)从更高层获取过滤器参数,语法是什么样的。我希望是这样的:
直接来自 parent ,例如:
<MyView>
<MyView.ViewModel Filter="All">
</MyView>
<MyView>
<MyView.ViewModel Filter="Some">
</MyView>
或者从用户控件向上看,例如:
<UserControl.Resources>
<MyViewModel x:Name="MyViewModel" Filter="{Binding FilterTypeFromDataContextHigherUpTheTree}"/>
</UserControl.Resources>
但我不知道是否可以直接从父级引用静态资源 View 模型以设置属性,或者语法是什么样的。
我也不知道是否有更简单的方法可以做到这一点,因为我怀疑我的方法不是很优雅。
真正的问题是如何将参数传递给作为静态资源的 View 模型
最佳答案
尽管可以将 ViewModel 存储为资源,但我们通常将 ViewModel 设置为 View 的 DataContext。然后,如果有人需要通过 View 访问 ViewModel,他们只需将 DataContext 转换为正确的 ViewModel 类型并直接访问它的属性。
如果你想为你的过滤器选择绑定(bind)路由,你有几个选择。如果子控件放置在模板(或样式)中的父控件内部,则可以将 Bnding Soure 设置为 RelativeSource.TemplatedParent。您也可以使用 ElementName,但前提是命名元素位于同一范围内(在上面的示例中,命名元素必须位于 MyView 内的某个位置)。
我能想到的最后一个选项是在 MyView 上为过滤器公开一个 DependencyProperty,然后将 ViewModel 绑定(bind)到该属性。这将有效地使过滤器冒泡,以便它可以在 MyView 之外访问,但我根本不喜欢这种方法,因为它只是为了将属性传递给 ViewModel 而向 View 添加属性。那不应该发生。 ViewModel 应该始终可以独立于 View 访问,这就是为什么我建议通过 DataContext 属性(推断)或通过专门用于 ViewModel 的自定义属性(显式)公开它。
关于silverlight - 如何将父 View 中的参数设置为在用户控件中声明为静态资源的 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7984547/