你在作弊。这是4个问题!
1)
关于如何对视图和视图模型进行分组,我看到人们将视图和视图模型放在同一个命名空间/文件夹中,而其他人则根据功能将它们分开到不同的文件夹中。最适合您的选择是适合您/您的团队的。没有“正确”的方式。
2)
保持干燥 - 所以不要重复自己。重用代码是完全明智的。如果您有共同的课程,请保持共同。至于命名,类的名称应该有助于解释它的作用:我相信你能够弄清楚 NavigationService、NavigationMenuItem 和 NavigationMenuView 类做了什么,并且可能可以将一个很好的心理模型放在一起他们相关。所以 - 如果命名一个类 BlahViewModel 或 BlahModel 对你有用,那就去做吧。
3) 实现视图:
一个窗口总是独立显示。页面旨在用于导航应用程序(通常带有后退和前进按钮,例如 Internet Explorer)。页面必须托管在 NavigationWindow 或 Frame 中。如果您正在查看动态添加/删除内容,将内容添加到 ItemsControls(TabControl 等),那么您将希望创建用户控件。您可以将用户控件放在 Page 和 Window 对象中,放入其他控件等中,这确实是 WPF 开发人员的主力。
4)
您有多种选择:
1)快速而肮脏的方法是创建 DataTemplate ,在获得 X 类型的 ViewModel 后,加载 ViewModel 并将其应用于其数据上下文。这将允许您将 ViewModel 直接注入控件并具有正确的 View 渲染。
一个例子:
查看.xaml
<ContentControl Content="{Binding Error, Mode=OneWay}" />
视图模型:
private void ReceiveError(ErrorViewModel errorModel)
{
//if (errorModel.AcceptCommand==null || errorModel.AcceptCommand is NoOpCommand)
errorModel.AcceptCommand = new DelegateCommand(ClearError);
Error = errorModel;
}
public ErrorViewModel Error
{
get { return _error; }
set
{
_error = value;
_propertyChangedHelper.NotifyPropertyChanged(this, () => Error);
}
}
Styles.Xaml(资源字典)
<DataTemplate DataType="{x:Type vm:ErrorViewModel}">
<DataTemplate.Resources>
<conv:CustomisableBooleanToVisibilityConverter x:Key="VisibilityConverter" TrueValue="Visible" FalseValue="Collapsed" />
</DataTemplate.Resources>
<Popup AllowsTransparency="True" PopupAnimation="Fade" Placement="Center" StaysOpen="True"
PlacementTarget="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type v:ModuleView}}}"
IsOpen="True" Width="400" SnapsToDevicePixels="True"/>
所以你可以看到我将我的视图模型直接注入到内容控件中,它使用绑定到视图模型类型的数据模板来为其查找视图。
2)
更好的选择是使用 DataTemplateSelector。这基本上允许您指定哪些模板可用于控件,然后使用您编写的逻辑来确定要使用的数据模板。你可以在这里找到一个例子。
3)
使用将 UI 控件抽象出来的框架。Microsoft 有一个框架(免费)可以执行此操作,称为 Prism。基本上,不是将用户控件直接添加到 TabControl、ItemsControl 等,而是将控件添加到命名的“区域”。该区域映射到底层控件,并放置了一个适配器来管理当您要求它时如何添加/删除 UserContorl。您可以在此处找到对此的深入讨论。但请注意,Prism 是一个应用程序框架,因此实现它不是 3 小时的工作。