博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF: 在MVVM中使用Navigtaion
阅读量:6256 次
发布时间:2019-06-22

本文共 5480 字,大约阅读时间需要 18 分钟。

Navigation可以很方便的在页面间进行切换,但是在MVVM模式下,使用Naviation会有一个问题,切换的逻辑需要在ViewModel层完成,但是Navigation需要知道页面的实例或者Uri才能进行切换,那我们如何在ViewModel与UI分离的情况下,用Navigation完成页面的切换呢?

假如有一个程序如下所示,点击Switch之后会从Summary Page切换到另一个页面Detail Page:

在MVVM中,我们需要有三个ViewModel,一个是SummaryViewModel对应SummaryPage, 一个是DetailViewModel对应DetailPage,再加上一个ControlViewModel负责通过改变CurrentPageViewModel来实现逻辑数据的切换并将其反应到UI,如下所示:

public class SummaryViewModel    {        public ObservableCollection
Summaries { get; set; } public SummaryViewModel() { Summaries = new ObservableCollection
(); } }
public class DetailViewModel    {        public ObservableCollection
Details { get; set; } public DetailViewModel() { Details = new ObservableCollection
(); } }
public class NavigationControlViewModelBase : ViewModelBase    {        private object currentPageViewModel;        public object CurrentPageViewModel         {             get            {                return currentPageViewModel;            }             set             {                 currentPageViewModel = value;                RaisePropertyChanged(() => CurrentPageViewModel);             }         }}public class ControlViewModel : NavigationControlViewModelBase    {        private SummaryViewModel summary;        public SummaryViewModel Summary { get { return summary; } set { summary = value; RaisePropertyChanged(() => Summary); } }        private DetailViewModel detail;        public DetailViewModel Detail { get { return detail; } set { detail = value; RaisePropertyChanged(() => Detail); } }        public ControlViewModel()        {            SwitchCommand = new RelayCommand(Switch);            Summary = new SummaryViewModel();            Detail = new DetailViewModel();            CurrentPageViewModel = Summary;            GenerateData();        }        public ICommand SwitchCommand {
get;set;} private void Switch() { if (CurrentPageViewModel == Summary) { CurrentPageViewModel = Detail; } else { CurrentPageViewModel = Summary; } } private void GenerateData() { var ran = new Random(); Summary.Summaries.Clear(); Detail.Details.Clear(); for (int i = 0; i < 100; i++) { Summary.Summaries.Add(new SummaryModel() { ID = ran.Next(0, 100) }); } for (int i = 0; i < 100; i++) { Detail.Details.Add( new DetailModel() { ID = i, Data1 = Guid.NewGuid().ToString().Substring(0, 4), Data2 = Guid.NewGuid().ToString().Substring(0, 4), Data3 = Guid.NewGuid().ToString().Substring(0, 4), Data4 = Guid.NewGuid().ToString().Substring(0, 4), Data5 = Guid.NewGuid().ToString().Substring(0, 4), }); } } }

添加一个类NavigationControlFrame继承Frame负责控制Navigation, 在这个类里有一个依赖属性CurrentPageObject,在XAML中会将它与ControlViewModel的CurrentPageViewModel绑定,CurrentPageViewMdoel改变时,触发OnCurrentPageObjectChanged。通过XAML里定义的ViewModel类型和Page Uri对应关系找到相应的页面进行切换:

class NavigationControlFrame : Frame    {        public NavigationControlFrame()        {            Navigated += navigationFrame_Navigated;        }        public static readonly DependencyProperty CurrentPageObjectProperty =            DependencyProperty.Register("CurrentPageObject", typeof(object), typeof(NavigationControlFrame), new PropertyMetadata(default(object), OnCurrentPageObjectChanged));                private static void OnCurrentPageObjectChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)        {            var navigationFrame = (NavigationControlFrame)dependencyObject;            var newValue = dependencyPropertyChangedEventArgs.NewValue;            if (newValue == null)            {                navigationFrame.Navigate(null);                return;            }            var pageUri = (string)navigationFrame.TryFindResource(newValue.GetType());            navigationFrame.Navigate(new Uri(pageUri, UriKind.Relative), newValue);        }        static void navigationFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)        {            if (e.ExtraData != null)            {                var control = e.Content as Page;                control.DataContext = e.ExtraData;            }        }        public object CurrentPageObject        {            get { return GetValue(CurrentPageObjectProperty); }            set { SetValue(CurrentPageObjectProperty, value); }        }    }

 

在XAML中在Resource中定义ViewModel与Page Uri的对应关系,添加NavigtaionControlFrame,并将CurrentPageObject绑定到CurrentPageViewModel,这样ControlViewModel中的CurrentPageViewModel变化时,对应的页面也会进行切换:

/DetailPage.xaml
/SummaryPage.xaml

 

 

转载于:https://www.cnblogs.com/nofireice/p/3250725.html

你可能感兴趣的文章
Sql Server系列:存储过程
查看>>
Pointer 指针
查看>>
使用sqlyog将sql server 迁移到mysql
查看>>
lost connection to mysql server reading initial communication packet
查看>>
Eucalyptus安装包的功能列表
查看>>
mongodbOperator
查看>>
从零开始学Java(一)基础概念——什么是"编程和软件开发"?
查看>>
Latency
查看>>
System.Collections 学习
查看>>
Python 安装pyautogui
查看>>
Keras AttributeError 'NoneType' object has no attribute '_inbound_nodes'
查看>>
Gabor滤波器学习
查看>>
更改linux系统提示信息
查看>>
阿里巴巴CI:CD之分层自动化实践之路
查看>>
HDU 1060:Leftmost Digit
查看>>
numpy利用数组进行数据处理
查看>>
【转】TCP 网络状态图详解
查看>>
SQL Server之 (二) SQL语句 模糊查询 空值处理 聚合函数
查看>>
All about Using Burp Suite
查看>>
Nikto and whatweb
查看>>