MVVM Master-Detail导航

最近在看Laurent Bugnion的Deep Dive MVVM,大神传授了很多技巧,本文只关注一点,如何从ViewModel发起页面导航。

本文的Demo也很简单,MasterPage使用ListBox加载一些信息,单击其中任意项,页面导航到DetailsPage并显示选择项的详情,如下图。

                                       MasterPage                        DetailsPage 

MasterPage绑定至MasterViewModel,DetailsPage绑定至DetailsViewModel,代码在此MvvmNavigationDemo.zip,以下将只介绍关键技术点。

 

一、声明INavigationService接口,并实现一个继承NavigationService类.

public interface INavigationService
   {
       event NavigatingCancelEventHandler Navigating;
       void NavigateTo(Uri uri);
       void GoBack();
   }

public class NavigationService : INavigationService
   {
       private PhoneApplicationFrame _mainFrame;

       public event System.Windows.Navigation.NavigatingCancelEventHandler Navigating;

       public void NavigateTo(Uri uri)
       {
           if (EnsureMainFrame())
           {
               _mainFrame.Navigate(uri);
           }
       }

       public void GoBack()
       {
           if (EnsureMainFrame() && _mainFrame.CanGoBack)
           {
               _mainFrame.GoBack();
           }
       }

       private bool EnsureMainFrame()
       {
           if(_mainFrame!=null)
           {
               return true;
           }
         
           _mainFrame = Application.Current.RootVisual as PhoneApplicationFrame;
           if (_mainFrame != null)
           {
               _mainFrame.Navigating += (s, e) =>
                                            {
                                                if (Navigating != null)
                                                {
                                                    Navigating(s, e);
                                                }
                                            };
           }
           return false;
       }
   }

 

二、 在MasterViewModel类中声明INavigationService字段及SelectedItem属性.

public class MasterViewModel : ViewModelBase
   {
       public INavigationService NavigationService { get; set; }

 

       public ObservableCollection<FriendViewModel> Friends
       {
           get;
           private set;
       }

 

       public const string SelectedFriendPropertyName = "SelectedItem";
       private FriendViewModel _selectedItem = null;
       public FriendViewModel SelectedItem
       {
           get { return _selectedItem; }
           set
           {
               if (_selectedItem == value)
                   return;

               var oldValue = _selectedItem;
               _selectedItem = value;
               RaisePropertyChanged(SelectedFriendPropertyName, oldValue, _selectedItem, true);
          
              if(NavigationService !=null)
               {

                   // 调用NavigationService实例方法,进行页面导航
                   NavigationService.NavigateTo(ViewModelLocator.DetailsPageUri);
               }
           }
       }

   }
注意,本处变更通知,使用的是ViewModelBase的重载方法,发起PropertyChanged事件并广播一个PropertyChangedMessage消息。本处另一重要技巧便是使用INavigationService接口调用导航方法。

image

 

三、DetailsViewModel中加入SelectedItem属性,在默认构造中注册接受PropertyChangedMessage消息,并在收到消息时,执行传入的Action。

public partial class DetailsViewModel : ViewModelBase
    {
        public const string SelectedFriendPropertyName = "SelectedItem";

        private FriendViewModel _selectedItem = null;
        public FriendViewModel SelectedItem
        {
            get
            {
                return _selectedItem;
            }

            set
            {
                if (_selectedItem == value)
                {
                    return;
                }

                _selectedItem = value;
                RaisePropertyChanged(SelectedFriendPropertyName);
            }
        }

        public DetailsViewModel(IFriendsService friendsService)
        {
            ……

            Messenger.Default.Register<PropertyChangedMessage<FriendViewModel>>(
                this,
                message =>
                    {
                        SelectedItem = null;
                        SelectedItem = message.NewValue;
                    });

            ……
        }

image

 

四、ViewModelLocator中分别向SimpleIoc注册MasterViewModel/DetailsViewModel,并加入Master/Detail属性。同时将Master的NavigationService字段赋值为NavigationService的实例。

public class ViewModelLocator
   {
       public static readonly Uri DetailsPageUri = new Uri("/DetailsPage.xaml", UriKind.Relative);

       static ViewModelLocator()
       {
           ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

           if (ViewModelBase.IsInDesignModeStatic)
           {
               SimpleIoc.Default.Register<IFriendsService, Design.DesignFriendsService>();
           }
           else
           {
               SimpleIoc.Default.Register<IFriendsService, FriendsService>();
           }

           SimpleIoc.Default.Register<MasterViewModel>();
           // Ensure VM
           var master = SimpleIoc.Default.GetInstance<MasterViewModel>();
         
          SimpleIoc.Default.Register<DetailsViewModel>();
           // Ensure VM
           SimpleIoc.Default.GetInstance<DetailsViewModel>();

           master.NavigationService = new NavigationService();
       }

       /// <summary>
       /// Gets the Main property.
       /// </summary>
       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
           "CA1822:MarkMembersAsStatic",
           Justification = "This non-static member is needed for data binding purposes.")]
       public MasterViewModel Master
       {
           get
           {
               return ServiceLocator.Current.GetInstance<MasterViewModel>();
           }
       }

       public DetailsViewModel Details
       {
           get
           {
               return SimpleIoc.Default.GetInstance<DetailsViewModel>();
           }
       }

}

 

Demo源代码:MvvmNavigationDemo.zip

转载于:https://www.cnblogs.com/winkia/archive/2012/04/24/2466911.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt MVVM(Model-View-ViewModel)是一种基于Qt框架的设计模式,用于构建用户界面(UI)和业务逻辑的解耦合的应用程序。它是基于传统的MVC(Model-View-Controller)模式的进一步演化。 在Qt MVVM中,Model负责数据的管理和操作,它提供了底层数据对象和数据操作的接口。View是用户界面的呈现,它通过绑定机制和ViewModel交互,以显示数据和响应用户的操作。ViewModel是连接Model和View的桥梁,它将Model的数据转化为View所需的格式,并将用户的输入和操作转化为Model所需的格式。ViewModel还提供了数据绑定机制,以确保Model和View之间的同步。 通过使用Qt MVVM,我们可以实现以下优点: 1. 解耦合:通过将业务逻辑与用户界面解耦合,使得代码易于维护和测试。ViewModel充当了Model和View之间的中间层,使得它们可以独立地进行修改和调整。 2. 可维护性:由于代码的解耦合,使得我们可以更容易地对应用程序进行修改和更新。当需要改变用户界面或业务逻辑时,只需要修改ViewModel或Model的代码,而不会影响其他部分。 3. 可测试性:MVVM模式提供了更好的测试性,我们可以更容易地编写单元测试,以验证Model和ViewModel的功能是否正常工作。这使得我们可以更好地管理和保证代码的质量。 4. 数据绑定:Qt MVVM提供了高效的数据绑定机制,使得我们可以非常简便地将数据与用户界面关联起来。这大大减少了手动更新UI的工作量,提高了开发效率。 总之,Qt MVVM是一种强大的设计模式,可以帮助我们构建易于维护和测试的应用程序。通过解耦合和数据绑定,它提供了一种更合理和高效的方法来管理用户界面和业务逻辑之间的交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值