你有没有调查过Prism http://compositewpf.codeplex.com/.
该框架允许您在 UI 中定义可以注册视图的区域。我相信这回答了您的第二个问题 (2)。
xmlns:cal="http://www.codeplex.com/prism"
<Window>
<!-- somehow I need to add the mapping from ViewModel to View -->
<Grid>
<!-- the main ViewModel -->
<ContentPresenter cal:RegionManager.RegionName="MainRegion"/>
</Grid>
</Window>
对于您的第一个问题(1),我们按以下方式构建我们的实体:
View - 我们有一个抽象基类,看起来类似于:
public abstract class ViewBase<T> : UserControl, IView<T> where T: IViewModel
{
public T ViewModel
{
get
{
return this.viewModel;
}
protected set
{
this.viewModel = value;
this.DataContext = this.viewModel;
}
}
public ViewBase(IUnityContainer container)
{
this.ViewModel = container.Resolve<T>();
}
}
然后,我们可以使用以下命令在 xaml 中创建视图:
<ui:ViewBase x:Class="MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:ui="NAMESPACE FOR VIEWBASE"
xmlns:vm="NAMESPACE FOR VIEWMODEL"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:TypeArguments="vm:MYVIEWMODEL">
在视图的后面代码中,我们执行以下操作:
public partial class MyView : ViewBase<IMyViewModel>
然后,使用基类中的构造函数来解析 ViewModel 并将其设置为其 DataContext。
这样您就可以按照预期设计视图 (3),并且不再需要 DataTemplate。
然后,我们使用 UnityContainer 注册视图,如下所示:
this.container.RegisterType<IMyView, MyView>();
this.container.RegisterType<IMyViewModel, MyViewModel>();
this.regionManager.RegisterViewWithRegion("MainRegion", typeof(IMyView));
请注意,此处的“MainRegion”与 MainWindow xaml 中指定的 RegionName 匹配。如果您想在同一区域显示多个视图,或者甚至将 MainWindow 分解为不同的区域,您可以进一步扩展它以使用 TabControl。
我希望这有帮助。