1

我已经为我的应用程序制作了一个根 AppView,一个根 AppViewModel 作为所有东西的容器。在应用程序视图中,我有一个 TabControl,每个选项卡都有自己的任务要做。一页导入数据、一页发布、一页管理等:

App_View[Model] // root
{ 
   TabTask1_View[Model], TabTask2_View[Model], TabTask3_View[Model] // tab items
} 

1)在 MVVM 中,我将整个视图和视图模型分组到主应用程序视图和应用程序模型视图中是标准的吗?

2) 在 MVVM 中,应该为每个视图和虚拟机实现模型?或者,如果我将整个模型实现为一个或两个类文件并在它们之间共享模型,这是否是标准的?我个人认为模型部分并不特定于某个视图,例如可以在代码中的任何地方使用的“学生”类,并且不限于某个视图。基于此,如果模型是通用的和共享的,那么遵循命名约定 Class + 'Model' 是否很好?像StudentModel?像我说的那样在通用或共享类名之后添加“模型”是否有帮助/有必要?

3) 在 WPF 中,实现视图的最佳方式是什么?我想非常轻松地编辑和设计,没有任何限制,并且它应该足够标准以涵盖未来的需求。有 4 个东西可以使用:Window、Page、UserControl 和 DataTemplate。哪一个是您的最佳选择?用户控件还是页面?

4) 在 WPF 中,如何基于 MVVM 方法在运行时动态加载 tabItem 内的 UserControl/Page(View)?

4

3 回答 3

2

你在作弊。这是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 小时的工作。

于 2013-06-21T09:24:14.497 回答
1

这不是答案,我将向您解释我的经验以及我如何处理 MVVM。我在 3 个月前开始使用 WPF,并处理了它。

  1. 对于每个新的主题/菜单/选项,我都会创建一个包含 ViewModel 和 Views 的新项目文件。所有业务类都收集在一个项目文件中,因为我可能必须在多个 ViewModel 中使用它。

  2. 是的,作为初学者,将类命名为 ...ViewModel 和 ..View 对我很有帮助。它让我很容易区分差异,而且向其他人解释你的课程也更容易/更容易(例如,如果你的编码有问题)

  3. 我将 UserControls 用于我们的不同视图,并将它们加载到 ContentControls 和 TabControls 中没有任何问题。

  4. 看看 Prism 的 MVVM 模式。

于 2013-06-21T08:39:12.493 回答
1

第 1 点:

这取决于。有两种广泛使用的方法 AFAIK。首先,正如您所说,将所有构成相同Window且具有直接依赖关系的 VM 分组,以形成一个显示您的实际程序结构的类结构。其次是您使用EventAggregator(Prism)/ Messenger(MVVM Light)松散链接VM而不是直接依赖的地方。

现在这两种方法都有其好处

  • 使用第一种方法很容易识别您的程序结构,因为您的 VM 依赖项清楚地显示了它,而第二种方法不是那么清晰可见。
  • 第二种方法在单元测试 VM 时对您有很大帮助,因为您不会被迫模拟/解决所有依赖的 VM,它还有助于在更改项目结构时对代码进行一些重构(考虑“插件”类)

哦,这些^^绝不是排他的。你可以把它们很好地混合在一起。

第 2 点:

模型与 View / VM 没有任何推荐的 1 <-> 1 关系,就像 View 与 VM 之间的关系一样。模型只是保存您的业务逻辑。我有一些应用程序有时根本没有模型。整个应用程序只使用 1 个模型(当后端是一个 c++ 库并且您只需使用 C++/CLI 模块与它交互)。是的,保持命名约定,以“模型”附加模型类名称

第 3 点

他们都怎么样?在适用的情况下使用它们。不要偏爱任何一个。当一个 View 组成多个其他部分时,这些部分本身就是一个带有 VM 的 View,我将拥有 aDataTemplate和 Data a UserControl。您的应用程序几乎总是使用 Window,并且Page我认为对于基于导航的应用程序很有用。ThinkPage是我用过最少的。

第 4 点

这是教程的问题。举一些例子,看看它是如何实现的,推理它并选择你的方法。如果您使用 VS2010 获得MVVM 在框中(这很棒。没有两种方法。真的希望这可以为 VS2012 更新,如果它还没有)。对于 VS2012,请查看显示概念的两个视图 MVVM CodeProject,然后您可以将其应用于ItemsControl您选择的任何一个。

最后,至少在您启动时,从使用 MVVM 帮助程序库开始。我更喜欢MVVM Light <- 该链接有几个视频库的作者展示了一些用法,你可以在这里找到关于它的大量帮助。如果您想自己做事,请从中学习基础知识,然后自己实施。如果你从第一天开始就走上正轨,那只是一个更长的学习曲线(只是我的看法)

于 2013-06-21T09:12:26.980 回答