繁体   English   中英

WPF MVVM-VM中的显示表单

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM