假设我有一个MainWindow和一个MainViewModel,我在这个例子中没有使用MVVM Light或Prism.
在这个MainWindow我想点击一个MenuItem或Button打开一个NewWindow.xaml不是UserControl.
我知道如何使用它在一个或一个现有的窗口中UserControl打开一个新的.UserControlContrntControlFrame
<ContentControl Content="{Binding Path=DisplayUserControl,UpdateSourceTrigger=PropertyChanged}" />
Run Code Online (Sandbox Code Playgroud)
码
public ViewModelBase DisplayUserControl
{
get
{
if (displayUserControl == null)
{
displayUserControl = new ViewModels.UC1iewModel();
}
return displayUserControl;
}
set
{
if (displayUserControl == value)
{
return;
}
else
{
displayUserControl = value;
OnPropertyChanged("DisplayUserControl");
}
}
}
Run Code Online (Sandbox Code Playgroud)
在ResourceDitionary对MainWindow我有:
<DataTemplate DataType="{x:Type localViewModels:UC1ViewModel}">
<localViews:UC1 />
</DataTemplate>
<DataTemplate DataType="{x:Type localViewModels:UC2ViewModel}">
<localViews:UC2 />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
问题是我想开一个新的Window,而不是一个UserControl.所以我使用这样的代码:
private ICommand openNewWindow;
public ICommand OpenNewWindow
{
get { return openNewWindow; }
}
public void DoOpenNewWindow()
{
View.NewWindowWindow validationWindow = new View.NewWindow();
NewWindowViewModel newWindowViewModel = new NewWindowViewModel();
newWindow.DataContext = ewWindowViewModel;
newWindow.Show();
}
Run Code Online (Sandbox Code Playgroud)
然后绑定OpenNewWindow到MenuItem或Button.
我知道这不是正确的方法,但是这样做的正确方法是什么?
谢谢!
Law*_*nce 23
使用此类应用程序需要解决两个问题.
首先,您不希望View-Model直接创建和显示UI组件.使用MVVM的一个动机是将测试能力引入到View-Model中,并且让这个类弹出新窗口使得这个类更难以测试.
您需要解决的第二个问题是如何解决应用程序中的依赖关系,或者在这个实例中 - 如何将View-Model"挂钩"到相应的View?通过使用DI容器给出了后一问题的可维持解决方案.Mark Seemann 在.NET中的依赖注入给出了这个主题的一个很好的参考.他实际上也讨论了如何解决第一个问题!
要解决前一个问题,需要在代码中引入一层间接,以使View-Model不依赖于创建新窗口的具体实现.下面的代码给出了一个非常简单的示例:
public class ViewModel
{
private readonly IWindowFactory m_windowFactory;
private ICommand m_openNewWindow;
public ViewModel(IWindowFactory windowFactory)
{
m_windowFactory = windowFactory;
/**
* Would need to assign value to m_openNewWindow here, and associate the DoOpenWindow method
* to the execution of the command.
* */
m_openNewWindow = null;
}
public void DoOpenNewWindow()
{
m_windowFactory.CreateNewWindow();
}
public ICommand OpenNewWindow { get { return m_openNewWindow; } }
}
public interface IWindowFactory
{
void CreateNewWindow();
}
public class ProductionWindowFactory: IWindowFactory
{
#region Implementation of INewWindowFactory
public void CreateNewWindow()
{
NewWindow window = new NewWindow
{
DataContext = new NewWindowViewModel()
};
window.Show();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
请注意,您IWindowFactory在View-Model的构造函数中执行了一个实现,并且该对象将委托创建新窗口.这允许您在测试期间将生产实现替换为不同的实现.
| 归档时间: |
|
| 查看次数: |
20421 次 |
| 最近记录: |