天天看點

WPF MvvmLight簡單執行個體(1) 頁面導航

原文: WPF MvvmLight簡單執行個體(1) 頁面導航 實作了那些功能,先看看截圖:

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

此文僅作學習中的記錄,希望對看到此文的同學有一點點的幫助。

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