[英]WPF MVVM - Display Form in VM
我是MVVM
新手,如果我在逻辑上做错了,请告诉我。
基本上frmEpisodeView.xaml
应该是在此处设置的启动窗口:
StartupUri="View/frmEpisodeView.xaml"
当此Windows加载时,我想检查用户是否已经使用了该应用程序,并且没有可用的registry key
。
我已经从下面的代码中为frmEpisodeView.xaml
设置了datacontext
,如下所示
DataContext = new EpisodeViewModel();
在My EpisodeViewModel.cs
,执行检查注册表项的逻辑
public EpisodeViewModel() {
if (Registry.GetValue("HKEY_CURRENT_USER", "URL", "") == null)
{
//OPEN FORM HERE FRMLOGINVIEW.XAML
ServerURL = Registry.GetValue("HKEY_CURRENT_USER", "URL", "").ToString();
}
}
在逻辑上,如果注册表项为空,则应该在用户登录的地方显示一个表单,然后该表单会将条目保存在该页面上。
如何使表格出现?
我认为最简单的方法是编写一个帮助程序类。 为此服务创建一个接口,然后实现ShowWindow(object DataContext)方法以显示您喜欢的窗口并设置datacontext。
class WindowService:IWindowService
{
public void showWindow<T>(object DataContext) where T: Window, new()
{
ChildWindow window = new T();
window.Datacontext = DataContext;
window.Show();
}
}
另一种非常优雅的方法是使用如下所示的Action( Source ):
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new MainViewModel(() => (new Window()).Show()); // would be actual window
}
}
public class MainViewModel
{
private Action popupAction;
public MainViewModel(Action popupAction)
{
this.popupAction = popupAction;
}
public ICommand PopupCommand { get; set; }
public void PopupCommandAction()
{
popupAction();
}
}
public class SomeUnitTest
{
public void TestVM()
{
var vm = new MainViewModel(() => { });
}
}
因此,我将如何首先将其作为一个快速示例进行说明。
视图模型
public class EpisodeViewModel
{
private readonly IEpisodeModel episodeModel;
private readonly IViewFinder viewFinder;
public EpisodeViewModel(IEpisodeModel episodeModel, IViewFinder viewFnder)
{
this.episodeModel = episodeModel;
this.viewFinder = viewFinder;
CheckLoginPassed(this.episodeModel.LoginPassed);
}
private CheckLoginPassed(bool loginPassed)
{
if (!loginPassed)
{
this.viewFinder.LoadView<ILoginView>();
}
}
}
IView界面
public interface IView
{
void Show();
}
模型介面
public interface IEpisodeModel
{
bool LoginPassed
{
get;
}
}
模型
public class EpisodeModel : IEpisodeModel
{
private bool loginPassed;
public EpisodeModel()
{
if (Registry.GetValue("HKEY_CURRENT_USER", "URL", "") == null)
{
loginPassed = false;
}
}
public bool LoginPassed
{
get
{
return this.loginPassed;
}
}
}
IViewFinder界面
public interface IViewFinder
{
void LoadView<T>();
}
取景器
public class ViewFinder : IViewFinder
{
private readonly IEnumerable<IView> availableViews;
public ViewFinder(IEnumerable<IView> availableViews)
{
this.availableViews = availableViews;
}
public void LoadView<T>()
{
var type = typeof(T);
foreach (var view in this.availableViews)
{
if (view.GetType().IsAssignableFrom(type))
{
view.Show();
}
}
}
我在编写此代码时就考虑到了IoC,如果您没有IoC,我真的希望获得一个IoC,因为它在解决依赖项时将提供巨大帮助。 这只是一个基本示例,我可能会有一个不同的对象,该对象仅用于检查将结果提供给Model
的注册表,但这应该提供一个起点。
因此,在引用ILoginView
这是一个仅继承自IView
的接口,它实际上并未提供任何详细信息。 IView
界面有点怪异,因为只要它们的视图也继承自“ Window”,它们就已经实现了Show
方法,因此实际上您不必执行任何操作,这只是提供了一种更简单的调用show的方法,而无需实际知道您正在调用的是一个Window
。
另一点是,尽管ViewFinder
可以用于一个小型项目,但它在这里相对简单。我可能会看一下MVVM Light之类的东西来管理我的MVVM处理,因为它附带了View处理和一个简单的Service Locator作为标准配置。
是的,这是执行MVVM时的典型问题。 这些问题中的许多问题可以概括为:如何在具体的用户界面中执行此操作或该具体的“操作”,因为我应该100%地将其放入视图模型中?
我强烈建议您在https://msdn.microsoft.com/zh-cn/library/gg406140.aspx(Microsoft Prism Library 5.0 for WPF开发人员指南)中找到此类问题以及许多其他相关问题。
我个人认为阅读本书非常高兴,而且作者显然知道他们所表达的内容。
最好的祝福,
亨里克·达尔
您总是可以将此视图代码放入App.xaml.cs
构造函数中:
public App()
{
if (Registry.GetValue("HKEY_CURRENT_USER", "URL", "") == null)
{
//OPEN FORM HERE FRMLOGINVIEW.XAML
StartupUri = new Uri("View/frmLoginView.xaml", UriKind.Relative);
ServerURL = Registry.GetValue("HKEY_CURRENT_USER", "URL", "").ToString();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.