如何使用 MVVM Light for WPF 浏览窗口? [英] How to navigate through windows with MVVM Light for WPF?
问题描述
我刚刚开始了一个新项目,其中表示层将由 WPF 完成,MVVM Light 由 GalaSoft 完成.>
我需要很多视图,但我不清楚如何通过窗口管理导航.
首先,MVVM Light 中提供的用于创建新的WPF MVVM 视图"的模板创建了一个新的 Window
,它不能用于按帧导航(我的意思是,通过放置一个mainView
中的框架并更改要导航的源路径).
对于我使用模板创建的所有视图,我是否只需要将 Window
更改为 Page
?
或者是否有其他方法可以使用 MVVM Light 工具包在 WPF 中执行导航?
最终我是这样做的.
按照 o_q 的思路,我创建了 NavigationWindow 作为 MainWindow 并将所有视图更改为页面.
然后,我创建了一个界面和一个使用导航的类:
公共接口 INavigationService{事件 NavigatingCancelEventHandler 导航;void NavigateTo(Uri pageUri);无效的返回();}公共类导航服务:INavigationService{私人导航窗口_mainFrame;#region INavigationService 的实现公共事件 NavigatingCancelEventHandler 导航;public void NavigateTo(Uri pageUri){如果(确保主框架()){_mainFrame.Navigate(pageUri);}}public void GoBack(){如果(确保主框架()&&_mainFrame.CanGoBack){_mainFrame.GoBack();}}#endregion私人布尔值确保MainFrame(){如果(_mainFrame != null){返回真;}_mainFrame = System.Windows.Application.Current.MainWindow 作为 NavigationWindow;如果(_mainFrame != null){//如果应用程序在设计工具内运行,则可能为 null_mainFrame.Navigating += (s, e) =>{如果(导航!= null){导航(s,e);}};返回真;}返回假;}}
然后,在 viewModelLocator 中,我创建了所有用于存储视图路径的常量字符串:
公共类 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 的单例:
公共部分类 App : System.Windows.Application{私有静态 IUnityContainer _ambientContainer;公共静态 IServiceLocator AmbientLocator { 获取;私人订制;}...private void Application_Startup(对象发送者,System.Windows.StartupEventArgs e){_ambientContainer =新的 UnityContainer();_ambientContainer.RegisterType(new ContainerControlledLifetimeManager());AmbientLocator = new UnityServiceLocator(_ambientContainer);ServiceLocator.SetLocatorProvider(() => AmbientLocator);
现在,在我的 ViewModelLocator 中,我可以注册一个Galasoft"消息来捕获所有事件并导航到一个页面;在我的构造函数中:
public ViewModelLocator(){创建主();创建前端();创建后端();创建启动();创建操作();创建登录();创建配置();CreateOutOfOrder();//设置启动页面...ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));Messenger.Default.Register(this, message =>{开关(message.StateInfo.StateType){案例 StateType.StartUpState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));休息;案例 StateType.LoginState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(LoginViewPath, UriKind.Relative));休息;案例 StateType.OperativeState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OperativeViewPath, UriKind.Relative));休息;案例 StateType.ConfigurationState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(ConfigurationViewPath, UriKind.Relative));休息;案例 StateType.ClosedState:案例 StateType.OutOfOrderState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OutOfOrderViewPath, UriKind.Relative));休息;默认:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));休息;}});}
通过这种方式,我让所有的 viewModel 保持无知"......他们对导航一无所知,而且我没有背后的代码.
如果我需要使用视图中的按钮进行导航,我可以从连接的 viewModel 解析 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 Startup 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 Light for WPF 浏览窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!