首先:此应用和问题仅供学习之用
我正在使用一个新的应用程序,当用户点击MainView中的Button时,我想要打开一个Window。在过去,我设计了一个只创建新窗口并显示它的命令
new RelayCommand((x)=>new SecondWindow().Show());
现在有了这个新项目,我试图将所有类完全分离。为实现这一目标,我的应用程序包含4个程序集(BL,COM,DAL和UI)。 与每个WPF应用程序一样,应用程序以MainWindow.xaml开头。 MainWindow.cs将创建它的MainWindowViewModel实例:
public ViewModel VM {get; private set;}
public class MainWindow(){
VM = new ViewModel();
InitializeComponent();
}
(已经违反松散耦合)(关于如何改善它的任何提示?)
我的最后一次尝试是在主窗口中创建第二个窗口的实例
<Window.Resources>
<local:SecondWindow x:Key="sw"/>
</Window.Resources>
并将其作为CommandParameter传递给我的命令
CommandParameter="{StaticResource sw}"/>
new RelayCommand((x)=> ((Window)x).Show());
这个解决方案有效,但有一个很大的缺点 - 第二个窗口是在应用程序启动后立即创建的 - 它也是ViewModel,它启动了一些繁重的进程(DB Connections等)。
我听说过IoC原则,但我真的不知道如何在wpf应用程序中使用它。
答案 0 :(得分:1)
你正在考虑正确的思路....当你的应用程序启动时,你基本上必须创建一个ViewModel列表,然后当用户按下按钮并将ViewModel的名称作为CommandParameter传递时,你可以在它们之间切换到你的命令处理程序....
您可能会发现此链接指向Rachel Lim的博客
https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/
另外,我不会在这里发布任何代码,因为它太复杂了。所以这里是一个下载到我能提出的最简单的例子
http://www.mediafire.com/download/3bubiq7s6xw7i73/Navigation1.rar
下载并取消RAR(使用win RAR)您需要逐步完成代码,弄清楚它的作用以及它如何进行修改然后根据您的需要进行修改......或修改您的需求以适应代码.....
该示例是对Rachel Lim示例的修改。它只包含Views和ViewModels,没有模型或数据。它演示了两种不同视图之间的切换。
更新1
具体参考演示代码....您的VM被添加到静态虚拟机集合(请参阅AddViewModel函数),例如,当您单击按钮时,每个视图(DataTemplate将View与ViewModel关联)都被选中,通过调用&#39; SelectViewCommand&#39;然后将Current_ViewModel设置为选定的ViewModel ...然后更新相应的ContentControl以显示当前选择的View ...
我知道这很困惑,也很难解释
按下按钮以更改视图&#39;您实际上是在更改ContentControl绑定的属性的值,因此您必须在ContentControl绑定的类的SAME实例中调用正确的SelectViewCommand ...
在演示中,您会在“LogOn_View”中看到这一点。我打电话给
Command="{Binding DataContext.SelectViewCommand, ElementName=Base_V}"CommandParameter="Main_ViewModel"
这里我在Base_ViewModel中调用SelectViewCommand(x:Name =&#34; Base_V&#34;在Base_View XAML中),这是因为我想要更改Base_View中显示的视图&#39 ; s&#39; ContentControl&#39;
在Main_View中我调用
Command="{Binding SelectViewCommand}" CommandParameter="MainV1_ViewModel"
这里我在Main_ViewModel中调用SelectViewCommand,因为我想更改MainView&#39; ContentControl&#39; ....中显示的视图。
答案 1 :(得分:0)
我通常创建一个WindowService类来管理MVVM中的窗口更改/对话框。拥有&#34;查看&#34; ViewModel中的代码(即Window.Show())违背了MVVM原则。例如:
public class WindowService : IWindowService
{
public void ShowDialog<T>(ViewModelBase viewModel) where T : IApplicationDialog
{
IApplicationDialog dialog = (IApplicationDialog)Activator.CreateInstance(typeof(T));
dialog.Show();
}
}
然后来自ViewModel的调用看起来像:
windowService.ShowDialog<SecondWindow>(new SecondWindowViewModel());
如果您正在使用DI,您可以将对IoC容器的引用传递给窗口服务并从中创建窗口实例而不是使用Activator.CreateInstance(我更喜欢DI方法)