【问题标题】:How to expose view-model properties as externally bindable dependency properties?如何将视图模型属性公开为外部可绑定的依赖属性?
【发布时间】:2011-11-10 10:39:30
【问题描述】:

我正在编写一个内部使用 MVVM 的 WPF 用户控件。为了开箱即用,它创建了自己的视图模型(这部分与问题无关)。

我的控件公开了许多依赖属性。主机视图(使用我的控件的人)可以设置这些 DP 或绑定到它们。其中一些 DP 具有相应的视图模型属性。

这就是我想要实现的(见图):我的控件视图中的 DP 绑定到视图模型的相应属性。此外,宿主视图也需要能够设置或绑定这些 DP——与使用任何其他控件的方式相同。

但是,一旦宿主视图设置或绑定了 DP 的值,原始绑定(内部绑定到控件的视图模型)就会丢失。这是因为每个 DP 只能有一个绑定集。所以这不起作用:

一种解决方案是使视图模型成为 DependencyObject 及其属性 DP。这样,我可以将控件的视图模型绑定到它的视图,而不是相反,有效地反转左箭头。但是,出于各种原因,我希望我的视图模型使用纯 C# 属性和 INotifyPropertyChanged。

关于如何将视图模型属性公开为外部可绑定依赖属性的任何想法?

编辑:

澄清要求:视图实际上并没有创建视图模型本身(我意识到这会违反关注点分离);相反,它使用视图模型定位器来执行此操作。 (这是一个非常模块化的企业应用程序。)我知道这不是一种典型的方法(请参阅 Rachel 的回答)。但是,接受所描述的设置,有什么方法可以达到预期的效果吗?

【问题讨论】:

  • 你确定在这种情况下使用 MVVM 是合理的吗?也许它不是适合这项工作的工具。
  • 同意@icebat。 VM 是关于业务逻辑的,业务逻辑不应该被封装在 UserControl 中。它应该是关于简化 UI 的一部分,因此只包含 UI 逻辑。我会考虑将拥有自己的 VM 的 UC 视为代码异味。

标签: wpf data-binding mvvm user-controls dependency-properties


【解决方案1】:

所以情况是你有VM和View,它们必须是相互绑定的数据,VM不能是DependencyObject?好吧,AFAIK,三重绑定 VM-V-Host 是不可能的。

一种可能的方法是在 View 中创建 DependencyProperties 的重复集。原始属性将绑定到 VM 并会影响 View 的外观,重复的属性将绑定到 Host 并以某种方式影响 VM(例如,使用 DP 更改逻辑)。

【讨论】:

  • 这就是我最终采用的方法。我实际上创建了一个实用方法来透明地创建第二个 DP 并将所有内容与事件处理程序挂钩。这不好,但这是我获得想要的结果的唯一方法。
【解决方案2】:

如果我为CustomControl 创建ViewModel,则预计用户将使用该ViewModel 作为CustomControl.DataContext。其他任何时候,我的 UserControl 都没有与之关联的 ViewModel。

例如,假设我想要一个 PopupControl。

我会在 UserControl 后面的代码中创建一个包含所有自定义属性和逻辑的 UserControl(无 ViewModel)

<local:Popup Header="{Binding PopupHeader}"
             IsVisible="{Binding IsVisible}" />

我将创建一个PopupViewModel 并构建我的PopupUserControl,期望DataContext 的类型为PopupViewModel

<DataTemplate DataType="{x:Type local:PopupViewModel}">
    <local:PopupView />
</DataTemplate>

<ContentControl Content="{Binding MyPopupViewModel}" />

IsVisiblePopupHeader 等属性将存在于 ViewModel 中,而不存在于 PopupUserControl

【讨论】:

  • 嗨,瑞秋,感谢您的回答。我确实意识到这是两种常用的方法。但是,在这种情况下,它们不是一个选项:我们的应用程序框架通过 VM 定位器自动创建视图模型,因此用户无法显式设置它,而且控件非常复杂,我不想在代码隐藏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
相关资源
最近更新 更多