Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何显示ViewModel中的视图,以及如何使用MVVM在WPF中设置该视图的数据上下文_C#_.net_Wpf_Mvvm_Prism - Fatal编程技术网

C# 如何显示ViewModel中的视图,以及如何使用MVVM在WPF中设置该视图的数据上下文

C# 如何显示ViewModel中的视图,以及如何使用MVVM在WPF中设置该视图的数据上下文,c#,.net,wpf,mvvm,prism,C#,.net,Wpf,Mvvm,Prism,如何从视图模型命令打开新视图(对话框),以及如何使用视图模型设置新视图的数据上下文。这个问题一直困扰着我,虽然有这么多的问题,但到目前为止,我对任何答案都不满意 因此,假设: 我有一个名为MainView的启动对话框,我显示该对话框并在App.xaml.cs(OnStartUp)方法中设置其数据上下文。在MainView中,有一个名为“打开新对话框”的按钮,该按钮的命令与MainViewModel中的委托命令绑定。因此,当用户点击此按钮时,该命令调用execute方法。 假设MainViewMo

如何从视图模型命令打开新视图(对话框),以及如何使用视图模型设置新视图的数据上下文。这个问题一直困扰着我,虽然有这么多的问题,但到目前为止,我对任何答案都不满意

因此,假设:

我有一个名为MainView的启动对话框,我显示该对话框并在App.xaml.cs(OnStartUp)方法中设置其数据上下文。在MainView中,有一个名为“打开新对话框”的按钮,该按钮的命令与MainViewModel中的委托命令绑定。因此,当用户点击此按钮时,该命令调用execute方法。
假设MainViewModel中的命令与视图中的按钮绑定如下

  public ICommand ShowNewDialogCommand
    {
       if(this._showNewDialogCommand == null)
        {
          this._showNewDialgoCommand = new DelegateCommand(ShowDialogFromVM);
        }
    }
    private void ShowDialogFromVM()
    {
    }

假设我要显示的新对话框是ListAllStudentsView,它的视图模型是StudentsView模型。那么,在不破坏MVVM模式的情况下显示此对话框的各种方法是什么?每种方法的优缺点是什么?

首先,我们需要创建一个带有datacontext集的视图(某处)。非常简单,我们实例化视图并将其传递给视图模型(假设视图在其构造函数中设置了其数据上下文)或手动设置它。如果我们愿意的话,视图也可以用XAML声明视图模型

方法1:

Window dialog = new ListAllStudentsView(new StudentsViewModel());
方法2:

Window dialog = new ListAllStudentsView();
dialog.DataContext = new StudentsViewModel();
方法3:

<Window.DataContext>
   <local:StudentsViewModel/>
</Window.DataContext>

现在我们需要将此代码(以及相关的
dialog.ShowDialog()
放在某个地方)。我看到两个选项,在命令的execute函数中,或者在视图的代码中(由命令的execute函数(如“RequestDialog”)引发的事件触发)


我更喜欢第一种,尽管它没有像MVVM那样严格,因为它更简单,代码更少,更易于管理。但是,如果您想严格遵守MVVM,我会让ViewModel在视图侦听的命令函数中引发一个类似“RequestDialog”的事件,并运行构造函数和ShowDialog()函数。

我使用
EventAggregator
模式和特定于WPF的
WindowManager
(a-la Caliburn.Micro)聆听ViewModels基于生命周期的事件(例如
Activate
DeActivate
等。然后WindowManager创建窗口并设置适当的DataContext和DataTemplate,或者在ViewModel变为非活动状态时关闭窗口。不过,这只是我的方法。我想大多数MVVM框架都会以自己的方式处理这个问题。HighCore,你能建议吗一个解释您使用的方法的链接这肯定高度依赖于您的框架和总体设计。LordTakkera,我想要一个不违反MVVM方法任何部分的通用方法LordTakkera,我认为MVVM要求我们不应在视图中直接使用view对象model@Yogesh乔希,母鸡ce事件引发技术,通过该技术,ViewModel没有视图的引用或知识。我包括了另一种方法,因为在我看来,过于严格遵守任何编程原则都可能导致问题,这可能是其中之一。Takkera,同样,当事件处理程序与事件绑定时,委托包含目标object属性,该属性保持对具有事件处理程序的对象的强引用。因此,即使在事件方法中,视图模型也会间接地使视图的对象足够真实。因为您是从视图模型开始的,如果您沿着树走得够远,视图模型将不得不与了解视图的人交谈。问题变成了您是否愿意划定这条界限?您完全可以使用HighCore建议的“WindowManager”类,或者多种不同方法中的任何一种。我刚刚给出了这两种方法(在我看来)不破坏MVVM概念的最简单方法。顺便说一句,ViewModels总是有一个对视图的引用,因为WPF将视图的各个部分附加到PropertyChanged事件。我的观点是,代码中没有魔法。最终,不管隐藏与否,视图模型都会对视图有某种了解。