目前我正在创建View和ViewModel的新实例,并在'Startup'应用程序事件处理程序中的应用程序中分配view.DataContext = vm
在“将视图应用于ViewModel”一章的http://msdn.microsoft.com/en-us/magazine/dd419663.aspx中,我已经读过将ViewModel对象绑定到通过资源进行查看是个好主意。
我是否正确理解使用建议的方法我应该:
我是对的吗?
P.S。实际上,我已经尝试过这样做,但很少有问题,想知道我是否按照正确的方式行事。如果不是,请指出我应该如何以正确的方式完成。
答案 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会自动执行此操作。
然后我就完成了。我不必再触摸我的资源文件了。 :)