WPF MvvmLight简单实例(1) 页面导航

原文:WPF MvvmLight简单实例(1) 页面导航

实现了那些功能,先看看截图:

操作描述:

在程序运行后,点击“Load”按钮,页面会加载PageOne,点击PageOne页面中的“Next”按钮即可进入PageTwo页面,

点击PageTwo页面中的“Next”即可进入PageThree页面,点击Back可返回Page1页面

第一步:新建工程并使用NuGet安装MvvmLight

第二步:添加Views文件夹并添加相应的ViewModel

本文主要描述如何使用MvvmLight实现简单的导航效果,所以页面基本上都是大同小异比较简单ViewModel也比较简单,所以这里只PageOne.xaml以及PageOneViewModel.cs

PageOne.xaml代码:

<Page x:Class="MvvmLightSample.Views.PageOne"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="clr-namespace:MvvmLightSample.Views"
      mc:Ignorable="d" 

      Title="PageOne">
    <Page.DataContext>
        <Binding Path="PageOne" Source="{StaticResource Locator}"></Binding>
    </Page.DataContext>
    <Grid Background="Orange">
        <TextBlock Text="1" Foreground="White" FontSize="30"></TextBlock>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock Text="{Binding Title}" FontSize="18" Foreground="White"></TextBlock>
            <Button Width="80" Height="20" Content="Click me!!!" Margin="0,20,0,0" Command="{Binding ChangeCommand}"></Button>
        </StackPanel>
        <Button Command="{Binding GoToNextCommand}"  Content="Next" Width="60" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,10,10"></Button>
    </Grid>
</Page>

PageOneViewModel.cs代码:

  public class PageOneViewModel : ViewModelBase
    {
        private INavigationService _navigationService;
        public ICommand GoBackCommand { get; set; }
        public ICommand GoToNextCommand { get; set; }
        public ICommand ChangeCommand { get; set;}
        private string _title;

        public string Title
        {
            get { return _title; }
            set
            {
                Set(()=>Title,ref _title,value);
            }
        }

        public PageOneViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;
            Title = "Please Click me!";
            GoBackCommand = new RelayCommand(GoBack);
            GoToNextCommand = new RelayCommand(GotoNext);
            ChangeCommand = new RelayCommand(ChangeTitle);
        }
        private void ChangeTitle()
        {
            Title = "Hello MvvmLight!!!";
        }
        private void GoBack()
        {
            _navigationService.GoBack();
        }
        private void GotoNext()
        {
            var navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
            navigationService.NavigateTo("PageTwo2");
        }
    }

第三步:修改ViewModelLocator.cs

 public class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<PageOneViewModel>();
            SimpleIoc.Default.Register<PageTwoViewModel>();
            SimpleIoc.Default.Register<PageThreeViewModel>();
            SimpleIoc.Default.Register<PageFourViewModel>();

            var navigationService = this.CreateNavigationService();
            SimpleIoc.Default.Register<INavigationService>(() => navigationService);
        }
        private INavigationService CreateNavigationService()
        {
            var nav = new NavigationService();

            var navigationService = new NavigationService();
            navigationService.Configure("PageTwo1", new Uri("/MvvmLightSample;component/Views/PageOne.xaml", UriKind.Relative));
            navigationService.Configure("PageTwo2", new Uri("/MvvmLightSample;component/Views/PageTwo.xaml", UriKind.Relative));
            navigationService.Configure("PageTwo3", new Uri("/MvvmLightSample;component/Views/PageThree.xaml", UriKind.Relative));
            navigationService.Configure("PageTwo4", new Uri("/MvvmLightSample;component/Views/PageFour.xaml", UriKind.Relative));
            return navigationService;
        }
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
        public PageOneViewModel PageOne
        {
            get
            {
                return ServiceLocator.Current.GetInstance<PageOneViewModel>();
            }
        }
        public PageTwoViewModel PageTwo
        {
            get
            {
                return ServiceLocator.Current.GetInstance<PageTwoViewModel>();
            }
        }
        public PageThreeViewModel PageThree
        {
            get
            {
                return ServiceLocator.Current.GetInstance<PageThreeViewModel>();
            }
        }
        public PageFourViewModel PageFour
        {
            get
            {
                return ServiceLocator.Current.GetInstance<PageFourViewModel>();
            }
        }
        public static void Cleanup()
        {
        }
    }

NavigationService.cs代码:

 public class NavigationService : ViewModelBase,INavigationService
    {
        private readonly Dictionary<string, Uri> _pagesByKey;
        private readonly List<string> _historic;
        private string _currentPageKey;
        #region Properties
        public string CurrentPageKey
        {
            get
            {
                return _currentPageKey;
            }

            private set
            {
               Set(()=>CurrentPageKey,ref _currentPageKey,value);
            }
        }
        public object Parameter { get; private set; }
        #endregion
        #region Ctors and Methods
        public NavigationService()
        {
            _pagesByKey = new Dictionary<string, Uri>();
            _historic = new List<string>();
        }
        public void GoBack()
        {
            if (_historic.Count > 1)
            {
                _historic.RemoveAt(_historic.Count - 1);

                NavigateTo(_historic.Last(), "Back");
            }
        }
        public void NavigateTo(string pageKey)
        {
            NavigateTo(pageKey, "Next");
        }

        public virtual void NavigateTo(string pageKey, object parameter)
        {
            lock (_pagesByKey)
            {
                if (!_pagesByKey.ContainsKey(pageKey))
                {
                    throw new ArgumentException(string.Format("No such page: {0} ", pageKey), "pageKey");
                }

                var frame = GetDescendantFromName(Application.Current.MainWindow, "MainFrame") as Frame;

                if (frame != null)
                {
                    frame.Source = _pagesByKey[pageKey];
                }
                Parameter = parameter;
                if (parameter.ToString().Equals("Next"))
                {
                    _historic.Add(pageKey);
                }
                CurrentPageKey = pageKey;
            }
        }

        public void Configure(string key, Uri pageType)
        {
            lock (_pagesByKey)
            {
                if (_pagesByKey.ContainsKey(key))
                {
                    _pagesByKey[key] = pageType;
                }
                else
                {
                    _pagesByKey.Add(key, pageType);
                }
            }
        }

        private static FrameworkElement GetDescendantFromName(DependencyObject parent, string name)
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);

            if (count < 1)
            {
                return null;
            }

            for (var i = 0; i < count; i++)
            {
                var frameworkElement = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
                if (frameworkElement != null)
                {
                    if (frameworkElement.Name == name)
                    {
                        return frameworkElement;
                    }

                    frameworkElement = GetDescendantFromName(frameworkElement, name);
                    if (frameworkElement != null)
                    {
                        return frameworkElement;
                    }
                }
            }
            return null;
        }

        #endregion
    }

源码下载地址:http://download.csdn.net/detail/qindongshou1/9481969

此文仅作学习中的记录,希望对看到此文的同学有一点点的帮助。

文中如果有不正确的地方欢迎指正。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9236637.html

时间: 2024-10-15 01:29:36

WPF MvvmLight简单实例(1) 页面导航的相关文章

WPF的页面导航

工作中之前接触过的WPF程序一直是使用TabControl作不同页面间的切换,每个Tab负责独立的功能,清晰简捷,所以一直就没有动力研究WPF自带的页面导航.(虽然接触过使用页面导航的WPF项目,也并没有去了解,而是似懂非懂地过去了.) 直到最近做的一个项目,用的还是TabControl,但在某个Tab里面,做的任务有些复杂,导致UI在操作前后会有很大的变化.很自然的想法就是在这个Tab中使用两个view(我并没有指明是UserControl还是Page),来回切换.然而粗略地调查了一下之后觉得

可以固定的顶部的导航菜单简单实例代码

可以固定的顶部的导航菜单简单实例代码:固定于网页顶部的导航栏效果在当下网站比较流行,所谓的固定于网页的顶部一般来说并不是一直固定于顶部,而是在开始是位于某一个位置,当下拉滚动条使其到达顶部的时候才会固定在顶部,下面通过代码实例介绍一下如何实现此效果.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" con

WPF单线程定时器 简单实例

//窗体加载完毕 void MyMessageBox_Loaded(object sender, RoutedEventArgs e) { //启动定时期倒计时,多线程计时 //System.Threading.Timer timer: //启动单线程计时 System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = new Tim

【Win10】页面导航的实现

注:本文基于 Windows 10 10240 及其 SDK 编写,若以后有变化,请以新版本为准. 页面导航我们是再熟悉不过了,浏览器.手机 App 大多都使用这种方式来展示内容.在 Windows 10 应用商店应用当中,也是使用这种方式来展示内容.具体是通过 Frame 这个控件来进行导航展示. 在 App.xaml.cs 文件中,我们可以看到创建了一个 Frame: 并且在下面,使用 Navigate 方法导航到 App 的主页 MainPage. 导航到某个页面使用的就是 Navigat

WinPhone学习笔记(一)——页面导航与页面相关

最近学一下Windows Phone(接下来简称“WinPhone”)的开发,在很久很久前稍探究一下WinPhone中对一些传感器的开发,那么现在就从头来学学WinPhone的开发.先从WinPhone的页面入手,在我印象中比较深刻的那番话:一台WinPhone设备就好比一个Web的浏览器,应用上每个界面就是一个网页,可以点击“后退”来返回之前的页面.这个类比我觉得相当的形象.这番话能引出WinPhone开发中一个比较常见的操作——页面导航,由这个页面导航还引出了别的方面的内容,如下面所示 那下

构建基于WinRT的WP8.1 App 01:页面导航及页面缓存模式

本篇博文主要阐述基于Windows Runtime的Windows Phone 应用页面间导航相关知识,主要分为以下几个方面: Window.Frame和Page概览 页面间实现跳转 处理物理后退键 页面的缓存 Window.Frame和Page概览 基于WinRT的Windows Phone 8.1,每个App只有一个Window. 每个Window都有自己的Frame和导航栈, 以及自己的Page. Window中有一个Frame,并且100%撑满可视区域,通常Frame也是100%撑满Wi

简单实例一步一步帮你搞清楚MVC3中的路由以及区域

我们都知道MVC 3 程序的所有请求都是先经过路由解析然后分配到特定的Controller 以及 Action 中的,为什么这些知识讲完了Controller Action Model 后再讲呢?这个东西我个人感觉比较的抽象吧!如如您有基础,看起来一点也不费力,如果您没有基础的话,您连Controller  Action 都不知道是什么,那您怎么理解路由呢?嘿嘿仅仅是个人的看法!如果您还没有了解MVC 3 的一些基本的信息请您按照我下面的导航来,先了解MVC 3 的其他知识,然后再看下这篇文章.

[Aaronyang] 写给自己的WPF4.5 笔记17[Page实现页面导航]

1. 第一个Page页使用 新建PageDemo解决方案,默认wpf应用程序 右键项目新建页,然后指定App.xaml的默认启动窗口,为Page1.xaml,F5运行项目 2.关于NavigationWindow不推荐使用,所以不讲解了,创建对象,指定Content为一个Page页,然后Show() 3.Page类 讲解几个可能跟Window不一样的属性 ShowsNavigationUI="False" 不显示导航栏,默认显示 新建Window1.xaml窗口,放入Frame,去掉默

【REACT NATIVE 系列教程之五】NAVIGATOR(页面导航)的基本使用与传参

本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2248.html 今天介绍一种应用开发中常用的负责页面切换及导航功能的组件:Navigator 一:Navigator 对于页面导航其实主要功能就是:每个页面都知道本身应该切换到哪个页面,并且切到的页面会记录从哪里来,如果要返回的话,知道返回到哪个页面.这一切都不需要再用逻辑管理!而且每个页面之间也可以进行参数传递,