【问题标题】:DataTemplate in Resource sets ViewModel to View, but thenResource 中的 DataTemplate 将 ViewModel 设置为 View,但随后
【发布时间】:2011-03-31 11:20:41
【问题描述】:

我正在尝试找出将视图的数据上下文设置为视图模型的多种不同方法。

我此刻正在关注的一个是这样的:

我有我的 MainWindowResource:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:vw="clr-namespace:DemoStuffPartII.View"
                xmlns:vm="clr-namespace:DemoStuffPartII.ViewModel">

<DataTemplate DataType="{x:Type vm:PersonViewModel}">
    <vw:PersonView />
</DataTemplate>

但这也是我立即陷入困境的地方。我知道我应该在视图中使用 ContentControl。但是配置它的最佳方法是什么?这个怎么办?

【问题讨论】:

    标签: wpf mvvm binding


    【解决方案1】:

    这就是您可以在 MVVM 应用程序中启用 ViewSwitching 导航的方式。

    其他缺失的位是: 在视图中->

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

    在 ViewModel ->(伪代码)

    Prop ViewModelBase CurrentPage.
    

    但是请注意,如果您只想将 ViewModel 连接到 View,您可以完全删除整个 DataTemplate-ContentControl,然后执行此操作。DataContext = new SomeViewModel();在代码隐藏中。

    我所知道的将 VM 连接到视图的最简洁的方法是使用 ViewModelLocator 模式。 Google ViewModelLocator。

    【讨论】:

    • 你在哪里说 Content="{Binding CurrentPage}",就我而言,CurrentPage 是 PersonViewModel,对吧?不过不得不问,既然已经在数据模板中指定了 ViewModel,为什么还要重新命名它呢?为什么不去 Content="{Binding}"?
    • DataTemplate 中指定的那个就是您“捕获”的那个。这是“目标”。我在绑定中指定的是“源”。但是,我确实觉得您在这里查看的是第 2 步,而不是从头开始。为了只使用 MVVM,您首先应该尽量保持简单 - 只需使用 this.DataContext = new SomeViewModel();
    • 是的,我可能以错误的顺序做一些事情,因为有时从哪里开始有点模糊。感谢您提供关于 ViewModelLocator 模式的分析器和提示!
    • np。请注意,Caliburn 和 Prism 都是非常好的框架,但恕我直言 MVVMLight 和 ViewModelLocator 模式是最简单和最轻量的方法。此外,Prism 也与 ViewModelLocator 配合得很好。
    【解决方案2】:

    有几种简单的方法可以将 ViewModel 绑定到视图。正如 Elad 提到的,您可以在代码隐藏中添加它:

    _vm = new MarketIndexVM();
    this.DataContext = _vm;
    

    或者,您可以在视图的 XAML 中将 ViewModel 指定为资源:

    <UserControl.Resources>
        <local:CashFlowViewModel x:Key="ViewModel"/>
        <Converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </UserControl.Resources>
    

    并将 LayoutRoot 的 DataContext 绑定到该资源:

    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}">
    

    【讨论】:

    • +1 这是天真的方式,但这是一开始就要走的路。
    • ` 怎么样?
    【解决方案3】:

    也许这并不能直接回答您的问题,但是您是否考虑过使用 MVVM 框架?例如,在Caliburn.Micro 你会这样做(非常基本的例子):

    public class ShellViewModel : Conductor<IScreen>
    {
      public ShellViewModel()
      {
        var myViewModel = new MyViewModel();
        this.ActivateItem(myViewModel);
      }
    }
    

    ShellView.xaml

    <Grid>
      <ContentControl x:Name="ActiveItem" />
    </Grid>
    

    MyView.xaml

    <Grid>
      <TextBlock>Hello world</TextBlock>
    </Grid>
    

    这是视图模型优先的方法。

    【讨论】:

    • 是的,这真的是让我自己想出关于 MVVM 的不同方法。在我的工作中,我们使用 prism,如果我没记错的话,它也与您建议的框架相同。
    • 很公平。我会说同时使用了 Caliburn.Micro 更胜一筹 - 例如,它的事件聚合器更易于使用并且可以与 POCO 对象一起使用,它还支持基于约定的绑定并具有非常强大的动作模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 2015-02-12
    • 1970-01-01
    相关资源
    最近更新 更多