MVVM - 如何将视图模型绑定到视图

时间:2011-04-28 15:39:50

标签: wpf mvvm binding view viewmodel

并提前感谢指导。我是MVVM的新手,我一直在通过文章学习。我想我已经走得很远,但有一件事似乎让我感到懊恼。我如何(不使用后面的代码中的代码)自动绑定到我想要的视图?据我了解,如果正确完成,这就是模式应该如何工作。我可以使用主窗口xaml中的代码来实现这一切,我甚至已经正确创建了一个资源字典(因为我可以在即时窗口中访问它。)我无法进入'自动化的下一步。 “这可能是我的设计,因为我对这种模式不熟悉,我完全可以接受这样做的可能性。这就是我的......

我有一个主窗口。这是一个有3行的网格。第一行是菜单。底行是状态栏。中间是一个堆栈面板,根据菜单选择动态加载内容。

我有2个视图用于填充此堆栈面板。一个只有一个样式文本框(帮助&关于。)另一个本身就是一个复合视图:搜索面板,结果网格和一个详细面板都加载到停靠管理器框架。

在后面的主窗口代码中,当用户单击菜单选项时,我清除堆栈面板的子项,实例化视图模型,实例化将视图模型传递到其中的视图,然后将新视图添加到子项中堆栈。这样做很好,但我不认为它与模式一致。

正如我所提到的,我有资源字典,但我不知道如何将它与堆栈面板相关联。我假设我必须使用绑定,但我无法弄清楚如何绑定到资源字典和/或如何告诉它更改命令的视图。

我读过的文章已将所有可用的视图模型添加到视图模型中的只读列表中,该列表基本上充当主窗口和所需的实际视图模型之间的路径。这似乎没问题,但我不明白为什么需要资源字典。此外,这些示例是向导实现,在这种情况下,这似乎是一个很好的方法,但我无法想象为具有100个视图模型的应用程序执行此操作。

再次,抱歉我的无知,但我希望有人可以指出我正确的方向。正如我所说,我已经阅读了大量的文章(约什史密斯,戴夫希尔等),我仍然没有建立联系,所以我希望得到一些具体的指导。 (我确实在途中有WPF Unleashed,但我希望在此之前取得一些进展。)

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

有关如何绑定视图模型的方法。

<强> 1。在XAML中创建静态资源。

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <local:MainViewModel x:Key="MainVM" />
  </Window.Resources>
  <Grid DataContext="{StaticResource MainVM}">

  </Grid>
</Window>

<强> 2。在View的构造函数中绑定

我知道你提到不使用代码,但这也是一个选择。只要你不在后面的代码中写任何逻辑,那么你就是好的。

public MainWindow()
{
  InitializeComponent();
  this.DataContext = new MainViewModel(); 
}

第3。使用ViewModelLocator绑定

您可能希望创建一个视图模型定位器类,该类负责为您的视图提供所需的视图模型。

这是一个viewmodel定位器类的简单示例。 viewmodel定位器类公开了一些viewmodel属性。然后,我们将这些属性绑定到视图的数据上下文。

 public class ViewModelLocator
  {
    public ViewModelLocator()
    {
      this.MainVM = new MainViewModel();
      this.AnotherVM = new AnotherViewModel();
    }
    public MainViewModel MainVM { get; set; }
    public AnotherViewModel AnotherVM { get; set; }
  }

然后,您可以在App.xaml中创建viewmodel定位器的静态资源,以使其可用于应用程序中的所有视图。

<Application x:Class="WpfApplication2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication2"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
      <local:ViewModelLocator x:Key="Locator" />         
    </Application.Resources>
</Application>

然后,您可以将视图的数据上下文绑定到viewmodel定位器的属性。

该示例告诉我们,如果viewmodel定位器(它是MainViewModel实例)绑定到Window的数据上下文,则绑定MainVM属性。

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding MainVM, Source={StaticResource Locator}}">

答案 1 :(得分:0)

我没有使用WPF,但我使用过Silverlight,我相信它应该是相同的。

当我创建View时,我在View中实例化了所需的ViewModel。我使用MEF进行依赖注入并以这种方式创建所需的VM,您可能不想沿着那条路走下去,但它可以给你一个想法。

e.g。视图模型:

[Export] // This attribute tells MEF to export an instance of this class
public class MyViewModel
{ ... }

查看

[Import] // MEF will look for any exported objects of type MyViewModel
public MyViewModel ViewModel
{
  get { return this.DataContext as MyViewModel; }
  set { this.DataContext = value; }
}

通过这种方式可以节省实例化VM和V,只需创建V并关注实例化VM并设置自己的DataContext。