【问题标题】:Is binding to a ViewModel property instead of using DataContext a valid way to connect a ViewModel to view?绑定到 ViewModel 属性而不是使用 DataContext 是将 ViewModel 连接到视图的有效方法吗?
【发布时间】:2018-03-21 09:06:54
【问题描述】:

我在 WPF 中读到的关于 MVVM 的大部分内容都是关于通过以某种方式将视图的 DataContext 设置为视图模型的实例来将视图连接到视图模型。我不喜欢使用 DataContext,因为它没有输入,因此智能感知不起作用。

我正在考虑使用一种方法,其中视图具有一个名为 ViewModel 的属性,该属性设置为该属性的一个实例。由于此属性具有特定类型,因此我可以像这样绑定到视图模型的属性

<TextBlock Text="{Binding Path=ViewModel.Property1, ElementName=_viewWindow}"/>

其中 _viewWindow 是应用于视图类的名称(例如可以是 Window 或 UserControl)。虽然这比通过 DataContext 绑定要冗长一些,但它的优点是智能感知可以工作。

视图模型将实现 INotifyPropertyChanged。

这是一种有效的方法吗?在我读过的关于 MVVM 的任何文章中,我都没有看到任何对这种方法的引用,但这似乎是一个合理的想法。

除了更短的绑定语法之外,使用 DataContext 还有其他优点吗?

我在另一个答案中看到的一件事是添加一个将 DataContext 转换为视图模型类型的属性。

【问题讨论】:

  • 你会从哪里得到INotifyPropertyChanged
  • ViewModel 将实现INotifyPropertyChanged。我认为数据绑定更新应该适用于这种方法。
  • 为顶级元素设置的DataContext被所有子元素继承。它确实缩短了绑定路径。如果您需要 Intellisense 支持,请查看d:DataContext / d:DesignInstance example 1d:DataContext / d:DesignInstance example 2
  • @ASh - 这是一个有趣的想法,我用它做了一些实验。 Intelisense 将显示我的视图模型的属性,但也会显示许多其他属性。如果我键入视图模型上不存在的属性,它也不会标记错误。它还要求我的视图模型具有默认构造函数。使用我上面描述的方法,检查似乎更加严格。所以DataContext 的主要优势似乎是我视图控制树下任何位置的短路径语法?
  • " 它还要求我的视图模型有一个默认构造函数" - 不是真的,如果没有默认 ctor,请设置 IsDesignTimeCreatable=False。 “如果我键入视图模型上不存在的属性,它不会标记错误” - 它对我有用。即使在 VS 2010 中。

标签: .net wpf


【解决方案1】:

如果您通过 XAML 设置数据上下文,您的智能感知将起作用。

<Window 
...>
<Window.DataContext>
    <MyViewModel />
</Window.DataContext>

如果您不喜欢将视图耦合到特定实现,则实际上可以为视图模型使用接口:

<Window
...>
<Window.DataContext>
    <x:Type Type="IMyViewModel" />
</Window.DataContext>

然后您需要通过后面的代码设置 DataContext。

public class MyView
{
    public MyView(IMyViewModel myViewModel)
    {
        this.DataContext = myViewModel;
    }
}

【讨论】:

  • 这很有帮助,但智能感知不能像绑定到特定属性一样工作(参见我上面关于设置设计实例的评论)。我没有意识到将 DataContext 设置为类型对象是以这种方式工作的——MS 是否在某处记录了这一点?
  • @Shane 嗯,奇怪的是我在智能感知方面从来没有遇到过任何困难。有时,一旦数据上下文发生变化,可能需要重新构建以帮助移动事物。此外,通过 XAML 设置数据上下文不限于窗口,几乎可以在任何框架元素(即网格、列表框等)上设置。here is some more info I found on MSDN
  • 我之前在 xaml 中看到过数据上下文设置,但对我来说新的是将它设置为视图模型的类型,而不是您在上面所做的视图模型的实例。似乎您在设计时告诉 VS 在运行时将 DataContext 设置为什么类型。
  • 啊抱歉,是的,它不是很出名,我不久前才偶然发现它。它对智能感知的影响基本上与 IsDesignTimeCreatable=false 相同,我想类似的事情正在幕后发生。不幸的是,我在 MSDN 上找不到任何关于它的文档。
  • 我喜欢这个解决方案,但智能感知并不适合我。您使用的是什么版本的 Visual Studio?我在 2 台计算机上尝试过,行为是相同的。如果我输入{Binding Path= 并按Ctrl-Space,我会看到视图模型的属性,但如果我输入的不是有效属性,它不会显示波浪线。我正在使用 VS 2017。
猜你喜欢
  • 1970-01-01
  • 2016-08-15
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 2016-07-11
  • 1970-01-01
相关资源
最近更新 更多