如何使用MVVM导航窗口进行WPF? [英] How to navigate through windows with MVVM Light for WPF?

查看:194
本文介绍了如何使用MVVM导航窗口进行WPF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始一个新的项目,其中表示层将由WPF完成,而GalaSoft的 MVVM Light



我需要很多意见,而且我不清楚如何通过Windows管理导航。



首先,MVVM Light中提供的模板用于创建新的WPF MVVM视图,创建一个新的窗口,不可用于按帧导航(我的意思是,放置一个框架在 mainView 中,并将源路径更改为导航)。



我只需要更改窗口页面为我使用模板创建的所有视图



或有没有一种不同的方法来使用MVVM Light工具包来执行WPF导航?

解决方案

最后我这样做了。 p>

按照o_q的想法,我创建了NavigationWindow作为MainWindow,并将所有视图更改为页面。



然后,我创建了一个使用导航的界面和类:

  public interface INavigationService 
{
事件NavigatingCancelEventHandler导航;
void NavigateTo(Uri pageUri)
void GoBack();
}

public class NavigationService:INavigationService
{
private NavigationWindow _mainFrame;

#region实现INavigationService

public event NavigatingCancelEventHandler导航;
public void NavigateTo(Uri pageUri)
{

if(EnsureMainFrame())
{
_mainFrame.Navigate(pageUri);
}

}

public void GoBack()
{
if(EnsureMainFrame()
& _mainFrame .CanGoBack)
{
_mainFrame.GoBack();
}

}

#endregion

private bool EnsureMainFrame()
{
if(_mainFrame! = null)
{
return true;
}

_mainFrame = System.Windows.Application.Current.MainWindow as NavigationWindow;

如果(_mainFrame!= null)
{
//如果应用程序在设计工具中运行,则可以为null
_mainFrame.Navigating + =(s,e )=>
{
if(Navigating!= null)
{
浏览(s,e);
}
};

返回true;
}

return false;
}

}

然后,在viewModelLocator中,我创建了将const字符串存储到我的视图的路径:

  public class ViewModelLocator 
{

#region视图路径

public const string FrontendViewPath =../Views/FrontendView.xaml;
public const string BackendViewPath =../Views/BackendView.xaml;
public const string StartUpViewPath =../Views/StartUpView.xaml;
public const string LoginViewPath =../Views/LoginView.xaml;
public const string OutOfOrderViewPath =../Views/OutOfOrderView.xaml;
public const string OperativeViewPath =../Views/SubViews/OperativeView.xaml;
public const string ConfigurationViewPath =../Views/SubViews/ConfigurationView.xaml;
#endregion

在App.cs中,在Application_Startup事件处理程序中,借助于Unity IoC我注册了一个NavigationService的单例:

  public partial class App:System.Windows.Application 
{

private static IUnityContainer _ambientContainer;
public static IServiceLocator AmbientLocator {get;私人集合}

...

private void Application_Startup(object sender,System.Windows.StartupEventArgs e)
{


_ambientContainer =
new UnityContainer();

_ambientContainer.RegisterType< INavigationService,NavigationService>(new ContainerControlledLifetimeManager());

AmbientLocator = new UnityServiceLocator(_ambientContainer);
ServiceLocator.SetLocatorProvider(()=> AmbientLocator);

现在,在我的ViewModelLocator中,我可以注册一个Galasoft消息来捕获所有的事件和导航到页面在我的构造函数中:

  public ViewModelLocator()
{
CreateMain();
CreateFrontend();
CreateBackend();
CreateStartUp();
CreateOperative();
CreateLogin();
CreateConfiguration();
CreateOutOfOrder();


//设置Sturtup页面...
ServiceLocator.Current.GetInstance< INavigationService>()。NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));

Messenger.Default.Register< MoveToViewMessage>(this,message =>
{
switch(message.StateInfo.StateType)
{
case StateType.StartUpState:

ServiceLocator.Current.GetInstance< INavigationService>()。NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));
break;
case StateType.LoginState :
ServiceLocator.Current.GetInstance< INavigationService>()。NavigateTo(new Uri(LoginViewPath,UriKind.Relative));
break;
case StateType.OperativeState:
ServiceLocator。 Current.GetInstance< INavigationService>()。NavigateTo(new Uri(OperativeViewPath,UriKind.Relative));
break;
case StateType.ConfigurationState:
ServiceLocator.Current.GetInstance< INavigationService& ()。NavigateTo(new Uri(ConfigurationViewPath,UriKind.Relative));
break;
case StateType.ClosedState:
case StateType.OutOfOrderState:
ServiceLocator.Current.GetInstance< INavigationService>()。NavigateTo(new Uri(OutOfOrderViewPath,UriKind.Relative));
break;
默认值:
ServiceLocator.Current.GetInstance< INavigationService>()。NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));
break;
}
});

}

这样,我保留所有的viewModelsignorant。 ..他们不了解任何关于导航,加上我没有代码背后。



如果我需要通过使用视图导航,我可以解决NavigationService从连接的视图模型,并导航到我需要的页面。



最重要的是,它的工作原理!


I've just started a new project in which the presentation layer will be done by WPF and MVVM Light by GalaSoft.

I need a lot of views and it's not clear to me how to manage navigation through windows.

First of all, the templates offered in MVVM Light for creating a new "WPF MVVM View" create a new Window that is not possible to use for navigation by frame (I mean, by putting a frame in mainView and changing the source path to navigate).

Do I simply have to change Window to Page for all the views I create using templates?

Or is there a different way to perform navigation in WPF with the MVVM Light toolkit?

解决方案

Eventually I did it this way.

Following the idea of o_q, I created NavigationWindow as MainWindow and changed all the the views to page.

Then, I created an inteface and a class which using Navigation:

public interface INavigationService
{
    event NavigatingCancelEventHandler Navigating;
    void NavigateTo(Uri pageUri);
    void GoBack();
}

public class NavigationService : INavigationService
{
    private NavigationWindow _mainFrame;

    #region Implementation of INavigationService

    public event NavigatingCancelEventHandler Navigating;
    public void NavigateTo(Uri pageUri)
    {

        if (EnsureMainFrame())
        {
            _mainFrame.Navigate(pageUri);
        }

    }

    public void GoBack()
    {
        if (EnsureMainFrame()
            && _mainFrame.CanGoBack)
        {
            _mainFrame.GoBack();
        }

    }

    #endregion

    private bool EnsureMainFrame()
    {
        if (_mainFrame != null)
        {
            return true;
        }

        _mainFrame = System.Windows.Application.Current.MainWindow as NavigationWindow;

        if (_mainFrame != null)
        {
            // Could be null if the app runs inside a design tool
            _mainFrame.Navigating += (s, e) =>
            {
                if (Navigating != null)
                {
                    Navigating(s, e);
                }
            };

            return true;
        }

        return false;
    }

}

Then, in viewModelLocator I created all the const string nedded to store the paths to my views:

public class ViewModelLocator
{

    #region Views Paths

    public const string FrontendViewPath = "../Views/FrontendView.xaml";
    public const string BackendViewPath = "../Views/BackendView.xaml";
    public const string StartUpViewPath = "../Views/StartUpView.xaml";
    public const string LoginViewPath = "../Views/LoginView.xaml";
    public const string OutOfOrderViewPath = "../Views/OutOfOrderView.xaml";
    public const string OperativeViewPath = "../Views/SubViews/OperativeView.xaml";
    public const string ConfigurationViewPath = "../Views/SubViews/ConfigurationView.xaml";
    #endregion

In App.cs, in the Application_Startup event handler, with the help of Unity IoC I registered a singleton of NavigationService:

public partial class App : System.Windows.Application
{

    private static IUnityContainer _ambientContainer;
    public static IServiceLocator AmbientLocator { get; private set; }

    ...

   private void Application_Startup(object sender, System.Windows.StartupEventArgs e)
    {


       _ambientContainer =
           new UnityContainer();

       _ambientContainer.RegisterType<INavigationService, NavigationService>(new ContainerControlledLifetimeManager());

       AmbientLocator = new UnityServiceLocator(_ambientContainer);
       ServiceLocator.SetLocatorProvider(() => AmbientLocator);

Now, in my ViewModelLocator, I can register a "Galasoft" message to catch all the events and navigate to a page; in the constructor I have:

    public ViewModelLocator()
    {
        CreateMain();
        CreateFrontend();
        CreateBackend();
        CreateStartUp();
        CreateOperative();
        CreateLogin();
        CreateConfiguration();
        CreateOutOfOrder();


        // Set Sturtup Page...
        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));

        Messenger.Default.Register<MoveToViewMessage>(this, message =>
        {
            switch (message.StateInfo.StateType)
            {
                case StateType.StartUpState:

                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));
                    break;
                case StateType.LoginState:
                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(LoginViewPath, UriKind.Relative));
                    break;
                case StateType.OperativeState:
                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(OperativeViewPath, UriKind.Relative));
                    break;
                case StateType.ConfigurationState:
                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(ConfigurationViewPath, UriKind.Relative));
                    break;
                case StateType.ClosedState:
                case StateType.OutOfOrderState:
                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(OutOfOrderViewPath, UriKind.Relative));
                    break;
                default:
                    ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));
                    break;
            }
        });

    }

In this way I keep all the viewModels "ignorant"... they don't know anything about navigation, plus I don't have code behind.

If I need to navigate by using a button from a view I can resolve NavigationService from the connected viewModel and navigate to the Page I need.

And, most important thing, it works!

这篇关于如何使用MVVM导航窗口进行WPF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆