如何使用 MVVM Light Toolkit 打开新窗口
我在 WPF 应用程序中使用 MVVM Light 工具包。我想知道从现有窗口打开新窗口的最佳方法是什么。我有这个 MainViewModel
,它负责我的应用程序的 MainWindow
。现在,在 MainView
中,单击按钮后,我想在其顶部打开第二个窗口。我已将 RelayCommmand
绑定到 Button
的 Command
。在 RelayCommand
的方法中,我可以创建一个新的窗口对象并简单地调用 Show()
,如下所示:
var view2 = new view2()
view2.Show()
但我认为 ViewModel 不应该负责用于创建新的 view2
对象。我已阅读这篇文章 WPF MVVM Get Parent from VIEW MODEL 其中 Bugnion建议将消息从 viewmodel1
传递到 view1
,然后 view1
应创建新的 view2
。但我不确定他将消息传递给 view1 到底是什么意思? view1
应该如何处理该消息?在它的代码后面还是什么?
问候, 纳比尔
I am using MVVM Light toolkit in my WPF application. I would like to know what is the best approach for opening a new window from an existing window. I have got this MainViewModel
, which is responsible for MainWindow
of my application. Now in the MainView
, on a button click, I would like to open a second window on top of it. I have got RelayCommmand
binded to the Button
's Command
. In the RelayCommand
's method, I can create a new window object and simply call Show()
, something like this:
var view2 = new view2()
view2.Show()
but I don't think the ViewModel should be responsible for creating the new view2
object. I have read this post WPF MVVM Get Parent from VIEW MODEL where Bugnion has suggested to pass message to the view1
from the viewmodel1
and then view1
should create the new view2
. But I am not sure what does he actually mean by passing the message to the view1
? How should the view1
handle the message? In it's code behind or what?
Regards,
Nabeel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
将消息从 ViewModel1 传递到 View1 意味着使用 MVVM Light Toolkit 中的消息传递功能。
例如,您的 ViewModel1 可能有一个名为 ShowView2Command 的命令,然后它会发送一条消息来显示视图。
View1 将在其后台代码中注册接收消息,并在收到正确消息时显示 View2。
Passing a message from ViewModel1 to View1 means to use the messaging capabilities in the MVVM Light Toolkit.
For example, your ViewModel1 could have a command called ShowView2Command, then it would send a message to display the view.
View1 would register to receive messages in its code behind and display View2 when it receives the correct message.
你为什么走这条路?很简单。如果您将按钮替换为切换按钮、超链接或任何其他数量的类似按钮的控件,则无需更新“代码隐藏” - 这是 MVVM 模式的基本原则。在新的切换按钮(或其他)中,您最终仍然会绑定到相同的命令。
例如,我正在为一位想要拥有 2 个 UI 的客户创建一个项目 - 其中一个在各方面(在演示方面)都将完全不同。水平选项卡与垂直 RadPanelBar(想想手风琴)用于导航。这两个视图都可以指向相同的 viewModel - 当用户单击视图 1 中的“工作订单”选项卡时,它会触发与面板栏中的“工作订单标题”中触发的相同“WorkOrderCommand”。
在代码隐藏模型中,您必须编写两个单独的事件。在这里你只需要编写一个代码。
此外,它允许设计师使用 Blend 创建他们想要的任何布局。只要他们有钩子(EventToCommand 控件),我(作为开发人员)就不会关心最终产品的外观。
松耦合的力量非常强大。
Why do you go this route? Its simple. If you replace your button with a toggleButton, or a hyperlink, or any other number of button-like controls, you don't need to update your "code behind" - its a basic principle of the MVVM pattern. In your new toggleButton (or whatever), you still end up binding to the same exact Command.
For example, I'm creating a project for a client who wants to have 2 UI's - one is going to be fundamentally different in every way, in terms of presentation. Horizontal tabs vs Vertical RadPanelBar (think Accordion) for navigation. Both of these views can point to the same viewModel - when a user clicks the Work Order tab in View 1, it fires the same "WorkOrderCommand" that's fired in the Work Order Header in the panel bar.
In a code-behind model, you'd have to code two separate events. Here you only have to code one.
Furthermore, it allows a designer using Blend to create any layout they want. As long as they have the hooks (EventToCommand control) in place, myself (as a developer) couldn't care less what the final product looks like.
Loose coupling is incredibly powerful.
您可以这样做,就像您需要创建一些事件并在视图中注册这些事件并在视图模型中调用它们一样。然后打开该弹出窗口。
这个示例
就像视图中的
MainView mn=new MainView();
在此处注册事件,就像mn.POpUpEvent +=
一样,单击选项卡按钮两次并在寄存器弹出窗口中 注册事件方法右侧打开弹出窗口的代码。
You can do in this way like you need to create some events and register those in view and call these in view model.and open that pop up window.
Like This example
inside the view
MainView mn=new MainView();
Register the event here like thake
mn.POpUpEvent +=
than click on tab button double timeand in registers popup method right the code for opening the pop up window.
除非我错过了这里的要点 - 如果我要使用后面的代码,那么为什么不直接实现button_click事件并打开第二个视图呢?
Bugnion 似乎建议的是 view1 ->按钮点击->中继命令->视图模型1 ->留言->视图1-> view1.cs->开放视图 2.
无论如何,通过编写代码隐藏都会牺牲可测试性,所以为什么要走这么长的路呢?
Unless I am missing the point here - if I were to use the code behind, then why not directly implement button_click event and open the second view?
What Bugnion seems to be suggesting is view1 -> button click -> relay command -> viewmodel1 -> message -> view1 -> view1.cs -> open view 2.
You are going to sacrifice testability anyhow by writing code-behind, so why take such a long route?
您可以使用通用接口将视图特定功能抽象为服务。在视图层中,您可以提供这些服务的具体实例,并使用 IoC 容器和依赖注入技术构建视图模型。
在您的情况下,您可以构建一个接口 IWindowManager 或具有所需方法的类似接口。这可以在您的视图层中实现。我最近写了一篇小博文,演示如何从视图模型中抽象出对话框行为。类似的方法可用于任何与用户界面相关的服务,例如导航、消息框等。
此链接可能对您有帮助 http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html
许多人还使用从视图模型触发事件的方法,这些方法是订阅 view.cs 文件,然后执行 MessageBox 或任何其他 UI 相关操作。我个人喜欢注入服务的方法,因为这样您就可以提供同一服务的多个实现。一个简单的例子是如何在 Silverlight 和 Windows Phone 7 应用程序中处理导航。您可以使用相同的视图模型,但根据应用程序类型注入导航服务的不同实现。
You can abstract the view specific features into services using generic interface. In the view layer you can provide concrete instances of these services and build view models using the IoC container and Dependency Injection technique.
In your case you can build an interface IWindowManager or something similar which has the required method. This can be implmented in your view layer. I wrote a small blog post recently demonstrating how to abstract the dialog behaviour out of view model. Similar apporach can be used for any user interface related service like Navigation, MessageBoxes etc.
This link might be helpful for you http://nileshgule.blogspot.com/2011/05/silverlight-use-dialogservice-to.html
Many people also use the approach of firing events from view models which are subscribed on the view.cs file and from there the MessageBox or any other UI related action is performed. I personally like the approach of injecting services because then you can provide multiple implementations of the same service. A simple example would be how navigation is handled in Silverlight and Windows Phone 7 applications. You can use the same view model but inject different implementations of the Navigation service based on the application type.
我发现解决这个问题的最佳方法是从 ViewModel 打开和关闭窗口。作为这个 链接建议,
DialogCloser
类,GalaSoft.MvvmLight.ViewModelBase
的 Base ViewModel 以及其他成员。完成后,使用此视图模型作为其他视图模型的基础。DialogCloser.DialogResult
依赖项属性与基础视图模型中的CloseWindowFlag
属性绑定。然后您可以从视图模型中打开/关闭/隐藏窗口。
I find the best way to approach this, is opening and closing the window from the ViewModel. As this link suggests,
DialogCloser
classGalaSoft.MvvmLight.ViewModelBase
with there additional members. Once done, use this viewmodel as base for other viewmodels.DialogCloser.DialogResult
dependency property with theCloseWindowFlag
property in the base viewmodel.Then you can open/close/hide the window from the viewmodel.