如何在 WPF 应用程序中捆绑 View、ViewModel 和 DataTemplate 以便于重用?

2024-04-19

情况:

我想创建一个由 ViewModel 驱动的灵活应用程序。

基本流程是这样的:

  1. 设计主ViewModel
  2. 创建一个 UserControl 作为视图,并为主 ViewModel 创建一个 DataTemplate 以选择该视图
  3. 如果有子组件,则由子 ViewModel 建模
  4. 创建一个 UserControl 作为 View 和一个 DataTemplate 供子 ViewModel 选择该 View

如果需要呈现子视图模型,则可以通过 DataTemplate 来完成。

这个做法也可以看看here http://paulstovell.com/blog/mvvm-instantiation-approaches(选项 8)。

所以主窗口 xaml 看起来像这样:

<Window>
    <!-- somehow I need to add the mapping from ViewModel to View -->
    <Grid>
        <!-- the main ViewModel -->
        <ContentPresenter Content="{Binding Path=Content}"/>
    </Grid>
</Window>

The Content属性可能包含一个视图模型,其中包含名为的元素列表Children它关联的 DataTemplate 可能如下所示: 子项也可以通过合适的 DataTemplate 灵活呈现。

<UserControl>
    <Grid>
        <StackPanel>
            <!-- display the child ViewModels  in a list -->
            <ItemsControl ItemsSource="{Binding Path=Children}" />
         </StackPanel>
    </Grid>
</UserControl>

问题:

  1. 我应该如何组织视图模型、视图及其数据模板,这样我就不需要在主窗口中对它们进行硬连线?

  2. 然后我如何将其连接到主窗口?

  3. 如果它是可存根的,那就太好了,即我可以在设计时使用设计时 dataContext 查看结果。

基本上我想捆绑 View、ViewModel 和 DataTemplate,并能够在不需要了解细节的应用程序中使用它们(例如,某些子 ViewModel 实现某个接口并注入到主 ViewModel 中)。


你有没有调查过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。

我希望这有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 WPF 应用程序中捆绑 View、ViewModel 和 DataTemplate 以便于重用? 的相关文章

  • 如何使用 ASP.Net Core Identity 从登录用户检索 Google 个人资料图片?

    好的 我目前正在使用 ASP NET Core 1 1 2 和 ASP NET Core Identity 1 1 2 其中重要的部分是启动 cs看起来像这样 public void Configure IApplicationBuilde
  • 删除 QComboBox“下拉”动画

    我正在使用 Qt 4 8 并且想在单击 QComboBox 时摆脱 下拉 动画 我也想稍微移动一下 到目前为止 我一直在考虑重新实现 showPopup 和 hidePopup 但不知道如何使其工作 此外 每次我尝试使用 CSS 进行移动或
  • 用于生成 C++ 代码轮廓/图的工具 - 有这样的东西吗? [复制]

    这个问题在这里已经有答案了 我需要深入研究用 C 编写的软件组件并对其进行一些修改 我幻想生成一些代码映射 它将显示类之间的关系并引导我完成方法的流程 调用图 有这个工具吗 几年前 我使用 Rational Rose 建模工具 该工具具有对
  • 如何混淆整数?

    我需要从 C 中的整数列表生成唯一值的列表 我以为是 MD5 或类似的 但它们生成了太多字节 整数大小为 2 个字节 例如 我想获得单向通信 0 gt ARY812Q3 1 gt S6321Q66 2 gt 13TZ79K2 因此 在证明哈
  • 如何检查特定作业是否在quartz调度程序中运行#

    我正在使用石英调度程序根据触发器的用户输入来安排写入文件的作业 我想检查作业是否仍在 stop 方法中运行 如何检查作业是否仍在运行 public class JobScheduler static StdSchedulerFactory
  • web请求超时处理?

    HttpWebRequest request HttpWebRequest WebRequest Create url request Timeout 20000 using WebResponse response request Get
  • 运行时动态转换

    有没有一种方法可以在运行时动态转换 如以下伪代码 foreach DataRow row in table Rows foreach DataColumn col in table Columns if row col DBNull Val
  • 如何使用 Moq 模拟 Web 服务调用?

    The using下面点击了我不想实际点击的外部资源 我想测试someResult以及使用它的代码 但每次我运行单元测试时 该代码仍然尝试访问真正的 Web 服务 如何使用最小起订量来伪造对 Web 服务的真实调用 但不模拟使用中的其余代码
  • 从命名管道读取

    我必须实现一个 打印服务器 我有 1 个客户端文件和 1 个服务器文件 include
  • 结构体前向声明编译失败

    我有以下代码 但编译器说 sender wrapper 未定义 即使我向前声明了它 我不能对结构进行前向声明吗 用VS2003编译 struct send wrapper struct IPSend IPSend IPSend const
  • 为什么(错误地)使用 ref myarray[0] 传递数组可以工作,但仅在 32 位应用程序中有效?

    我在一些互操作中做了一些愚蠢的事情 使用DllImport 在某一时刻 但它仍然可以在 32 位机器上运行 在 64 位应用程序上做了哪些不同的操作 以及为什么 导致方法 1 的行为不同 方法一 错误的方法 ref byte param S
  • DISM.exe 返回代码?

    我有一个程序调用 dism exe 程序 它在后台运行一些命令 现在 我只检查返回代码 0 或其他任何内容 以显示进程失败或成功 我可以用什么来交叉检查返回代码以获得准确的返回错误 DISM 参考了哪些回报 评论中提供的链接DISMAPI
  • 使用事件处理程序与覆盖事件触发方法

    我正在创建 Button 的子类 并希望向其某些事件 例如 OnClick 添加自定义功能 哪种方式更理想 我是否重写 OnClick protected override void OnClick EventArgs e base OnC
  • System.Globalization.CultureInfo 不包含 Name 的定义

    我对 System Globalization CultureInfo 类和 System Globalization 命名空间有这个特殊问题 我从具有 CultureInfo 属性的 API 调用返回一个对象 语言 我能够成功地将其在客户
  • 如何使用 html 敏捷包获取自定义标签?

    需要创建摘要 索引 为此我有标签
  • 使用 MVVM 在 WPF 中打印 TreeView

    我有一个树视图来从文本文件返回文本搜索结果
  • 如何只应用一种 clang-format 操作?

    我想用clang 格式调整我的评论 但仅此而已 选项是 AlignTrailingComments bool 但是当我运行以下命令时 clang format 3 6 i style AlignTrailingComments true
  • C 中的静态和外部内联函数[重复]

    这个问题在这里已经有答案了 我正在尝试详细了解静态函数和外部函数之间的区别 我知道静态内联函数和外部内联函数之间的基本区别 我的理解如有错误请指正 静态内联函数仅对定义它的翻译单元可见 外部内联函数可以在多个翻译单元中访问 最好在头文件中定
  • 警告 C4172:返回局部变量或临时变量的地址[重复]

    这个问题在这里已经有答案了 可能的重复 指向局部变量的指针 https stackoverflow com questions 4570366 pointer to local variable 我在这个网站上阅读了很多关于同一问题的其他主
  • .NET Web API - 添加日志记录

    我正在寻找有关处理 API 日志记录的最佳方法的帮助 我想将所有请求和响应记录到 sql 或文本文件 如果这是最好的方法 目前我已经在 SQL Server 的日志表中插入一行 我使用名为 LogAction 的静态方法来执行此操作 并在

随机推荐