【问题标题】:WPF MVVM - instantiating a ViewModel from another ViewModelWPF MVVM - 从另一个 ViewModel 实例化一个 ViewModel
【发布时间】:2020-05-19 19:22:54
【问题描述】:

我是 MVVM 新手,还在学习。我使用下面链接中的文章作为示例来实现一个简单的应用程序,该应用程序带有一个选项卡式工作区,它使用两个视图:“所有客户”和“新客户”。

https://docs.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern#relaying-command-logic

在上面文章使用的示例中,shell 应用程序 (MainWindowViewModel) 使用带有两个按钮的控制面板:“查看所有客户”和“创建新客户”。当用户单击这些按钮时,相应的视图会在主 shell 的选项卡式工作区中打开。

我现在的问题是:如果我们想在“所有客户”视图上添加一个“创建新客户”按钮,并且当用户单击此按钮时,“新客户”视图将作为一个选项卡式工作区在主视图中打开shell,最好的方法是什么?

我是否需要使用消息服务向所有同事广播/发送“CreateNewCustomer”消息,例如,并让主 shell (MainWindowViewModel) 注册到“CreateNewCustomer”,然后它的操作是实例化“选项卡式工作区中的“新客户”视图?

或者有更好/更简单/更优雅的方法吗?请注意,我没有使用 Prism、MVVMLight 或任何其他 MVVM 框架。作为学习的一部分,我正在构建自己的框架。

非常感谢您抽出宝贵时间回答我的问题。

【问题讨论】:

  • IMO,您可以显示一个对话框窗口,其中包含创建新客户所需的字段,并在应用用户按下确定时将其添加到客户集合中

标签: c# wpf mvvm


【解决方案1】:

如果我按照你的描述进行。

你应该有一个 WindowViewmodel。

这可能为您的选项卡提供了一系列视图模型。或者如果它没有,它可以做到。

无论事情以何种方式进行,您正在处理的用户控件上都会有一个按钮,并且它是您要在其上显示其他内容的同一窗口的子窗口。

将 NewUserCommand 添加到 WindowViewmodel。此消息将 NewCustomerViewModel 添加到您的 tabcontrol 绑定到的集合中。这首先使用 viewmodel 将选项卡模板化为 NewCustomerView。

剩下的问题是如何从子用户控件中的按钮到窗口的视图模型。 您可以通过使用相对源绑定来做到这一点。 看起来像:

{Binding DataContext.NewUserCommand,
  RelativeSource={RelativeSource AncestorType={x:Type YourWindowType}}}

这假设您可以使用“选项卡式工作区”的选项卡控件。如果您以某种方式考虑 Windows,那么我建议您重新考虑。

我还要说,如果不选择一个框架来简化您的命令,学习 wpf 就已经够难了。我建议你看一下 mvvmlight 和 relaycommand 的源代码。有很多事情要做。 Messenger 也是一个非常方便使用的东西。顺便说一句,我经常不使用任何东西,只使用中继命令和信使 mvvmlight。

【讨论】:

  • 这很完美!感谢帮助!但是,有趣的是,如果我尝试使用相同的方法关闭我的工作区并绑定到CloseWorkspaceCommand,它就不起作用,但如果我不使用 relativeSource,它就会起作用。所以,这行不通:<Button Content="Cancel" Command="{ Binding Path=DataContext.CloseWorkspaceCommand, RelativeSource={ RelativeSource AncestorType={ x:Type vm:MainWindowView } } }"/> 但这行得通:<Button Content="Cancel" Command="{ Binding Path=CloseWorkspaceCommand }"/>。为什么?是的,我使用了可观察的视图模型集合。
  • 命令在按钮的数据上下文中。这意味着您的按钮可能在您的窗口中,而不是您的 tabcontrol 中的用户控件之一。如果你做了我上面描述的,那么每个选项卡项都有一个用户控件/视图,它的 datacontext 是绑定到它的 itemssource 的 observablecollection 中的相应视图模型。 tabcontrol 之外和窗口中的按钮将位于 windowviewmodel 的数据上下文中。
  • 我终于解决了。 CloseWorkspaceCommand 在选项卡式工作空间的基类中实现,所有工作空间都继承自该类。因此,我不能使用 MainWindowViewModel 的数据上下文的相对路径是有道理的。再次感谢安迪的所有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多