使用mvvmlight for win8 让GridViewItem项 实现动态命令导航

前言:

该技术前提是 已经掌握一定程度的mvvmlight for win8 技巧

实现思路:

通过Messenger 机制 动态发送导航参数 到 需要导航的page 完成导航

导航参数:

[csharp] view plain copy print ?
  1. public class NavigateParameter
  2. {
  3. private string pageType;
  4. public string PageType
  5. {
  6. get { return pageType; }
  7. set { pageType = value; }
  8. }
  9. private object parameter;
  10. public object Parameter
  11. {
  12. get { return parameter; }
  13. set { parameter = value; }
  14. }
  15. }


在 OnNavigated 到首页的地方 加入以下方法 注册 该处理通道

[csharp] view plain copy print ?
  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. base.OnNavigatedTo(e);
  4. this.prContent.IsIndeterminate = true;
  5. this.ContentFrame.Navigate(typeof(MainPage));
  6. this.TopFrame.Navigate(typeof(VideosPage));
  7. #region Messengers 消息处理中心
  8. Messenger.Default.Register<NavigateParameter>(this, "MenuNavigate", async s =>
  9. {
  10. var type = await Task.Run<Type>(() =>
  11. {
  12. var fullName = "IntTourism.View." + s.PageType;
  13. return Type.GetType(fullName);
  14. });
  15. if (null != s.Parameter)
  16. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
  17. this.ContentFrame.Navigate(type, s.Parameter));
  18. else
  19. await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
  20. this.ContentFrame.Navigate(type));
  21. });
  22. Messenger.Default.Register<NavigateParameter>(this, "TopFrameNavigate", async s =>
  23. {
  24. var type = await Task.Run<Type>(() =>
  25. {
  26. var fullName = "IntTourism.View." + s.PageType;
  27. return Type.GetType(fullName);
  28. });
  29. await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
  30. {
  31. if (!TopFrame.CurrentSourcePageType.Equals(type))
  32. if (null != s.Parameter)
  33. this.TopFrame.Navigate(type, s.Parameter);
  34. else
  35. this.TopFrame.Navigate(type);
  36. });
  37. });
  38. #endregion
  39. }


Unloaded 注销

[csharp] view plain copy print ?
  1. private void LayoutAwarePage_Unloaded(object sender, RoutedEventArgs e)
  2. {
  3. Messenger.Default.Unregister<NavigateParameter>(this, "MenuNavigate");
  4. Messenger.Default.Unregister<LogBean>(this, "LogError");
  5. Messenger.Default.Unregister<LogBean>(this, "TopBusy");
  6. Messenger.Default.Unregister<LogBean>(this, "ContentBusy");
  7. Messenger.Default.Unregister<LogBean>(this, "TopFrame");
  8. this.btnCancel.PointerPressed -= SendError;
  9. this.btnSend.PointerPressed -= SendError;
  10. }

以下为xaml 里 gridview 菜单的binding方式

注意:ItemClick 此处通过eventTocommand 将事件与 viewmodel中相应的命令进行了binding处理 请结合我上一篇文章 对EventTocomand这一概念进行理解

[html] view plain copy print ?
  1. <common:LayoutAwarePage x:Class="IntTourism.MainPage"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:i="using:IntTourism.Com.Transvalue.Tools"
  7. xmlns:ignore="http://www.ignore.com"
  8. xmlns:common="using:IntTourism.Common"
  9. xmlns:cmd="using:IntTourism"
  10. mc:Ignorable="d ignore"
  11. d:DesignHeight="1080"
  12. d:DesignWidth="1080"
  13. DataContext="{Binding Main, Source={StaticResource Locator}}"
  14. NavigationCacheMode="Required">
  15. <Viewbox>
  16. <Grid Width="1080" Height="1080" x:Name="root">
  17. <GridView HorizontalAlignment="Left"
  18. VerticalAlignment="Top"
  19. Width="1080"
  20. Height="1080"
  21. CanDragItems="false"
  22. IsRightTapEnabled="False"
  23. ScrollViewer.HorizontalScrollBarVisibility="Hidden"
  24. IsSwipeEnabled="False"
  25. x:Name="gv"
  26. ItemsSource="{Binding MenuItems}"
  27. SelectionMode="None"
  28. >
  29. <GridView.Transitions>
  30. <TransitionCollection>
  31. <EntranceThemeTransition/>
  32. </TransitionCollection>
  33. </GridView.Transitions>
  34. <GridView.ItemContainerTransitions>
  35. <TransitionCollection>
  36. <EntranceThemeTransition/>
  37. </TransitionCollection>
  38. </GridView.ItemContainerTransitions>
  39. <GridView.HeaderTransitions>
  40. <TransitionCollection>
  41. <EntranceThemeTransition/>
  42. </TransitionCollection>
  43. </GridView.HeaderTransitions>
  44. <GridView.ItemTemplate>
  45. <DataTemplate>
  46. <GridViewItem>
  47. <Image Height="280" Width="280" Source="{Binding IconUrl}"/>
  48. <i:EventToCommandCollection.Items>
  49. <i:EventToCommand Command="{Binding MenuCMD}"
  50. CommandParameter="{Binding NavigateParameter}"
  51. NavigateUrl="{Binding NavigateUrl}"
  52. Event="ItemClick"/>
  53. </i:EventToCommandCollection.Items>
  54. </GridViewItem>
  55. </DataTemplate>
  56. </GridView.ItemTemplate>
  57. <GridView.ItemsPanel>
  58. <ItemsPanelTemplate>
  59. <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"
  60. ItemWidth="300" ItemHeight="300" MaximumRowsOrColumns="10"/>
  61. </ItemsPanelTemplate>
  62. </GridView.ItemsPanel>
  63. </GridView>
  64. </Grid>
  65. </Viewbox>
  66. </common:LayoutAwarePage>

下面这一段是ViewModel中对命令的处理,以及菜单的动态加载

[csharp] view plain copy print ?
  1. using GalaSoft.MvvmLight;
  2. using IntTourism.Com.Transvalue.Service;
  3. using GalaSoft.MvvmLight.Command;
  4. using System.Diagnostics;
  5. using Windows.UI.Xaml.Controls;
  6. using System.Collections;
  7. using System.Collections.ObjectModel;
  8. using IntTourism.Com.Transvalue.Model;
  9. using GalaSoft.MvvmLight.Messaging;
  10. using System;
  11. using System.ComponentModel;
  12. using System.Collections.Generic;
  13. using IntTourism.Com.Transvalue.Bean;
  14. using IntTourism.Com.Transvalue.Tools;
  15. using IntTourism.Com.Transvalue.Const;
  16. using System.Threading.Tasks;
  17. namespace IntTourism.ViewModel
  18. {
  19. /// <summary>
  20. /// This class contains properties that the main View can data bind to.
  21. /// <para>
  22. /// See http://www.galasoft.ch/mvvm
  23. /// </para>
  24. /// </summary>
  25. public class MainViewModel : ViewModelBase
  26. {
  27. private readonly IMainPageSerivce _dataService;
  28. #region Command
  29. private RelayCommand<ExCommandParameter> _menuCMD;
  30. /// <summary>
  31. /// Gets the MenuCMD.
  32. /// </summary>
  33. public RelayCommand<ExCommandParameter> MenuCMD
  34. {
  35. get
  36. {
  37. return _menuCMD ?? (_menuCMD = new RelayCommand<ExCommandParameter>(
  38. ExecuteMenuCMD,
  39. CanExecuteMenuCMD));
  40. }
  41. }
  42. private async void ExecuteMenuCMD(ExCommandParameter url)
  43. {
  44. await Task.Run(() =>
  45. {
  46. var nav = new NavigateParameter();
  47. nav.Parameter = url.Parameter;
  48. nav.PageType = url.NavigateUrl;
  49. if (null != url.NavigateUrl)
  50. {
  51. Messenger.Default.Send<bool>(true, "ContentBusy");
  52. Messenger.Default.Send<NavigateParameter>(nav, "MenuNavigate");
  53. }
  54. });
  55. }
  56. private bool CanExecuteMenuCMD(ExCommandParameter url)
  57. {
  58. if (null != url && !"".Equals(url))
  59. return true;
  60. else return false;
  61. }
  62. #endregion
  63. #region DataProperties
  64. #region MenuItems
  65. /// <summary>
  66. /// The <see cref="MenuItems" /> property's name.
  67. /// </summary>
  68. public const string MenuItemsPropertyName = "MenuItems";
  69. private ObservableCollection<MenuItem> _menuItems;
  70. /// <summary>
  71. /// Sets and gets the MenuItems property.
  72. /// Changes to that property's value raise the PropertyChanged event.
  73. /// This property's value is broadcasted by the MessengerInstance when it changes.
  74. /// </summary>
  75. public ObservableCollection<MenuItem> MenuItems
  76. {
  77. get
  78. {
  79. return _menuItems;
  80. }
  81. set
  82. {
  83. if (_menuItems == value)
  84. {
  85. return;
  86. }
  87. RaisePropertyChanging(() => MenuItems);
  88. var oldValue = _menuItems;
  89. _menuItems = value;
  90. RaisePropertyChanged(() => MenuItems, oldValue, value, true);
  91. }
  92. }
  93. #endregion
  94. /// <summary>
  95. /// The <see cref="WelcomeTitle" /> property's name.
  96. /// </summary>
  97. public const string WelcomeTitlePropertyName = "WelcomeTitle";
  98. private string _welcomeTitle;
  99. /// <summary>
  100. /// Sets and gets the WelcomeTitle property.
  101. /// Changes to that property's value raise the PropertyChanged event.
  102. /// This property's value is broadcasted by the MessengerInstance when it changes.
  103. /// </summary>
  104. public string WelcomeTitle
  105. {
  106. get
  107. {
  108. return _welcomeTitle;
  109. }
  110. set
  111. {
  112. if (_welcomeTitle == value)
  113. {
  114. return;
  115. }
  116. RaisePropertyChanging(WelcomeTitlePropertyName);
  117. var oldValue = _welcomeTitle;
  118. _welcomeTitle = value;
  119. RaisePropertyChanged(WelcomeTitlePropertyName, oldValue, value, true);
  120. }
  121. }
  122. #endregion
  123. /// <summary>
  124. /// Initializes a new instance of the MainViewModel class.
  125. /// </summary>
  126. public MainViewModel(IMainPageSerivce dataService)
  127. {
  128. _dataService = dataService;
  129. InitPropertyChanged();
  130. _dataService.GetItemData(
  131. async (items, error) =>
  132. {
  133. if (await Pollute.ReportError(error, "GetItemData", ErrorDesc._E01))
  134. {
  135. Messenger.Default.Send<bool>(false, "ContentBusy");
  136. return;
  137. }
  138. var data = await items;
  139. foreach (var item in data)
  140. item.MenuCMD = MenuCMD;
  141. MenuItems = data;
  142. Messenger.Default.Send<bool>(false, "ContentBusy");
  143. });
  144. }
  145. #region PropertyChangeMethods
  146. /// <summary>
  147. /// 初始化相关方法
  148. /// </summary>
  149. private void InitPropertyChanged()
  150. {
  151. PropertyChanging += PropertyChangingMethod;
  152. PropertyChanged += PropertyChangedMethod;
  153. }
  154. //private static Dictionary<Predicate<string>, Action> PropertyChangingActions;
  155. //private static Dictionary<Predicate<string>, Action> PropertyChangedActions;
  156. private void PropertyChangedMethod(object sender, PropertyChangedEventArgs e)
  157. {
  158. }
  159. private void PropertyChangingMethod(object sender, PropertyChangingEventArgs e)
  160. {
  161. }
  162. #endregion
  163. public override void Cleanup()
  164. {
  165. // Clean up if needed
  166. base.Cleanup();
  167. }
  168. }
  169. }

菜单实例数据:

[csharp] view plain copy print ?
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Threading.Tasks;
  4. using IntTourism.Com.Transvalue.Bean;
  5. using IntTourism.Com.Transvalue.Model;
  6. using IntTourism.Com.Transvalue.Service;
  7. namespace IntTourism.Com.Transvalue.Service.Impl
  8. {
  9. public class MainPageService : IMainPageSerivce
  10. {
  11. public void GetData(Action<DataItem, Exception> callback)
  12. {
  13. var item = new DataItem("Welcome to MVVM Light");
  14. callback(item, null);
  15. }
  16. public void GetItemData(Action<Task<ObservableCollection<MenuItem>>, Exception> callback)
  17. {
  18. var result = Task.Run(() =>
  19. {
  20. var items = new ObservableCollection<MenuItem>();
  21. var menu1 = new MenuItem();
  22. menu1.IconUrl = "../Assets/ICON/交通.png";
  23. menu1.NavigateUrl = "IntMaps";
  24. items.Add(menu1);
  25. var menu2 = new MenuItem();
  26. menu2.IconUrl = "../Assets/ICON/娱乐.png";
  27. menu2.NavigateUrl = "IntMaps";
  28. menu2.NavigateParameter = "Play";
  29. items.Add(menu2);
  30. var menu3 = new MenuItem();
  31. menu3.IconUrl = "../Assets/ICON/景点.png";
  32. menu3.NavigateUrl = "SceneViewGroup";
  33. items.Add(menu3);
  34. var menu4 = new MenuItem();
  35. menu4.IconUrl = "../Assets/ICON/购物.png";
  36. menu4.NavigateUrl = "IntMaps";
  37. menu4.NavigateParameter = "Buy";
  38. items.Add(menu4);
  39. var menu5 = new MenuItem();
  40. menu5.IconUrl = "../Assets/ICON/专题旅游.png";
  41. menu5.NavigateUrl = "SceneViewGroup";
  42. menu5.NavigateParameter = "Travel";
  43. items.Add(menu5);
  44. var menu6 = new MenuItem();
  45. menu6.IconUrl = "../Assets/ICON/实用信息.png";
  46. items.Add(menu6);
  47. var menu7 = new MenuItem();
  48. menu7.IconUrl = "../Assets/ICON/武汉之最.png";
  49. items.Add(menu7);
  50. var menu8 = new MenuItem();
  51. menu8.IconUrl = "../Assets/ICON/住宿.png";
  52. menu8.NavigateUrl = "IntMaps";
  53. menu8.NavigateParameter = "Rest";
  54. items.Add(menu8);
  55. var menu9 = new MenuItem();
  56. menu9.IconUrl = "../Assets/ICON/推荐线路.png";
  57. items.Add(menu9);
  58. //var menu10 = new MenuItem();
  59. //menu10.IconUrl = "../Assets/ICON/武汉介绍.png";
  60. //items.Add(menu10);
  61. var menu11 = new MenuItem();
  62. menu11.IconUrl = "../Assets/ICON/周边旅游.png";
  63. menu11.NavigateUrl = "IntMaps";
  64. menu11.NavigateParameter = "AllTravel";
  65. items.Add(menu11);
  66. var menu12 = new MenuItem();
  67. menu12.IconUrl = "../Assets/ICON/旅游动态.png";
  68. items.Add(menu12);
  69. var menu13 = new MenuItem();
  70. menu13.IconUrl = "../Assets/ICON/美图欣赏.png";
  71. items.Add(menu13);
  72. var menu14 = new MenuItem();
  73. menu14.IconUrl = "../Assets/ICON/天气预报.png";
  74. items.Add(menu14);
  75. var menu15 = new MenuItem();
  76. menu15.IconUrl = "../Assets/ICON/旅游咨询.png";
  77. items.Add(menu15);
  78. var menu16 = new MenuItem();
  79. menu16.IconUrl = "../Assets/ICON/美食.png";
  80. menu16.NavigateUrl = "IntMaps";
  81. menu16.NavigateParameter = "Eat";
  82. items.Add(menu16);
  83. return items;
  84. });
  85. callback(result, null);
  86. }
  87. }
  88. }


以上sample 数据 可以存入数据库中 进行动态配置,完成菜单的动态显示,降低了程序的耦合,增加了可配置性。

你可能感兴趣的:(使用mvvmlight for win8 让GridViewItem项 实现动态命令导航)