WPF + MVVM:如何通过资源字典显示VM

时间:2010-07-11 20:05:00

标签: wpf mvvm dictionary resources

目前我正在创建View和ViewModel的新实例,并在'Startup'应用程序事件处理程序中的应用程序中分配view.DataContext = vm

在“将视图应用于ViewModel”一章的http://msdn.microsoft.com/en-us/magazine/dd419663.aspx中,我已经读过将ViewModel对象绑定到通过资源进行查看是个好主意。

我是否正确理解使用建议的方法我应该:

  1. 在“MainPage”中创建一个资源,该资源将为每对View / ViewModel提供一个“DataTemplate”部分;
  2. 将ViewModel对象的实例绑定到MainPage?
  3. 我是对的吗?

    P.S。实际上,我已经尝试过这样做,但很少有问题,想知道我是否按照正确的方式行事。如果不是,请指出我应该如何以正确的方式完成。

2 个答案:

答案 0 :(得分:2)

这项技术的工作原理是,不是直接查找和创建视图,而是让wpf通过数据模板查找视图。因此,当您的应用程序资源中包含以下内容时。这会根据您要显示的ViewModel来驱动UI,而不必担心编码视图。

<DataTemplate DataType="{x:Type vm:MyViewModel}">
    <ui:MyView />
</DataTemplate>

注意:vm:和ui:只是在资源文件的top元素中声明的xml命名空间。 然后,您可以创建一个通过ContentControl

“查找”视图的通用窗口
<Window ...>
    <ContentControl Content="{Binding}" />
</Window>

var window = new Window();
window.DataContext = new MyViewModel();
window.Show();

这将显示嵌入MyView的窗口作为窗口的内容。如果您在视图中设置了绑定指向viewmodel中的属性,则连线成功。不需要'新'视图。只需将不同的视图模型重新分配给数据上下文,即可重用主窗口。

此外,如果您告诉我们您遇到的具体问题,如果上述情况不符合您的要求,我们将能够提供更具体的答案。

HTH

答案 1 :(得分:2)

我曾经为我的所有ViewModel / View做一个键/值对,就像aqwert建议的那样,但是一旦你得到了几十个,或者不止一个:),ViewModels开始变得相当乏味并且容易出现错别字。

我个人喜欢IValueConverter为我工作并使用Convention来查看View的位置。

例如,假设我在命名空间MyApp.ViewModels中有我的视图模型 以及命名空间MyApp.Views中的所有视图 我的所有虚拟机后面都有ViewModel后缀,所有观点后面都有View后缀

我所要做的就是:

1)让我的所有ViewModel继承自基类ViewModelBase

2)把它放在我的应用程序资源字典

<m:ViewModelConverter x:Key="ViewModelConverter"/>
<DataTemplate DataType="{x:Type vm:ViewModelBase}">
    <ContentControl Content="{Binding Converter={StaticResource ViewModelConverter}}"/>
</DataTemplate>

3)创建我的转换器,以下只是一个示例,您可以修改以符合您的惯例。

public class ViewModelConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            Type ViewModelType = value.GetType();
            string ViewNameSpace = ViewModelType.Namespace.Replace("ViewModel", "View");
            string ClassName = ViewModelType.Name.Replace("Model", string.Empty);
            Type ViewType = Type.GetType(string.Format("{0}.{1}", ViewNameSpace, ClassName));
            if (ViewType != null)
                return Activator.CreateInstance(ViewType);
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion
}

以上将尝试查找视图,如果不是,它将只返回它试图转换的ViewModel(WPF将只调用.ToString())

您不必担心将ViewModel实际连接到View的DataContext,因为WPF会自动执行此操作。

然后我就完成了。我不必再触摸我的资源文件了。 :)