【问题标题】:MVVM Passing data to dialog View ModelMVVM 将数据传递给对话框视图模型
【发布时间】:2011-01-22 23:14:01
【问题描述】:

我正在研究使用 MVVM,虽然我大部分都了解它,但有一件事我无法理解。

想象一下,我有一个 View 和 ViewModel 组合,它显示了一个 foobars 列表。当用户在列表中选择一个 foobar 并单击编辑按钮时,我希望 foobar 显示在弹出对话框窗口中,以便可以对其进行编辑。此对话框窗口(视图)将有自己的关联 ViewModel。

我知道按钮可以绑定到列表 ViewModel 上的命令,但是从这里我如何实例化 foobar 编辑器?

1) 我是否必须将消息发送回视图,这将打开对话窗口?如果是这样,这不是违背了拥有命令的目的吗?

2) foobar 如何被传递到编辑器的 ViewModel 中?如果是通过它的构造函数,这不是很难在 XAML 中声明 ViewModel 吗?

我觉得这是阻止我使用 MVVM 的最后一块拼图,我真的很想得到一个很好的解耦解决方案。

谢谢 马特

【问题讨论】:

    标签: wpf mvvm parameters viewmodel


    【解决方案1】:

    我可能会这样做:

    1. 附加到编辑按钮的命令启动编辑对话框,为其创建自定义 ViewModel (VM)。命令本身可能位于列表的 VM 或模型中(不太确定)。
    2. Foobar 编辑对话框的 VM 在其构造函数中获取对 Foobar 的引用。
    3. foobar 被克隆并被编辑。
    4. 只要用户在 foobar 编辑对话框中按下 OK,克隆的值就会被写回到 VM 中的原始 foobar(对话框关闭)。

    之所以需要克隆,是因为用户在接受编辑对话框中的更改之前不希望看到 foobar 列表中的更改。但是,如果在线编辑可以,则不需要克隆。

    更改会自动传播。

    PS:虽然我是 MVVM 的支持者,但从纯 MVVM 的角度来看,我不确定我的解决方案是否是正统的。

    【讨论】:

      【解决方案2】:

      来自 codeproject 的This article 显示了一个 WPF 对话框控件,它完全可以满足您的需要。这个实现是必要的原因是您不能将 Window 放在任何其他控件的可视化树中。这意味着开箱即用的 WPF 不允许您在窗口内创建对话框。所以上面的文章创建了一个子类ContentControl来创建一个窗口。

      无论如何,你把它放在你的 FooBarList 视图中

      <dialog:Dialog Content="{Binding Path=DialogViewModel}" /> 
      

      你确保你的资源字典中有这样的东西:

      <Style TargetType="{x:Type dialog:Dialog}">
       <Style.Triggers>
        <Trigger Property="HasContent" Value="True">
         <Setter Property="Showing" Value="True" />
        </Trigger>
       </Style.Triggers>
      </Style>
      

      只需要写这样的东西(为了让 WPF 工作,你需要实现 INotifyPropertyChanged):

      public Class FooBarListViewModel
      {
        IList<FooBar> FooBarList {get;set;}
        FooBar SelectedFooBar {get;set;}
        ViewModelBase DialogViewModel {get;set;}
      
        public EditFooBar(object param)
        {
          DialogViewModel = FooBar;
        }
      }
      

      要将视图链接到编辑 FooBar 到 FooBar ViewModel 只需执行类似的操作(最好在 Application.Resources 中,这样它是全局的)

      <DataTemplate DataType={x:Type vm:FooBarViewModel}>
        <vw:FooBarView/>
      </DataTemplate>
      

      (或可选:使用 IValueConverter 转换从 ViewModel like this post shows 获取您的视图)

      然后你就准备好了。听起来可能很多,但它确实让你解放了很多。

      【讨论】:

      • 这是一个有趣的方法。看着示例项目,我想知道我是否会因为失去普通窗口的一些功能(调整大小、无模式等)而感到厌烦。我开始认为,考虑一个根本不需要复杂对话框的设计可能值得我考虑——也许有一个 MDI 应用程序来代替。您对此有何看法?
      【解决方案3】:

      缺少的是负责 ViewModel 工作流的控制器。 Controller 创建 ViewModel 并在 ViewModel 之间传递必要的数据。

      WPF Application Framework (WAF) 项目包含展示其工作原理的示例应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-15
        • 2020-02-08
        相关资源
        最近更新 更多