如何使用MVVM导航窗口进行WPF? [英] How to navigate through windows with MVVM Light for WPF?
问题描述
我需要很多意见,而且我不清楚如何通过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屋!