【Windows Phone 8】使用MVVMLight框架
【简介】1.作者文章:http://www.galasoft.ch/mvvm/
2.可以通过Nuget下载MVVLight
【对比引用文件】
普通WindowsPhone引用
使用MVVMLight的WindowsPhone程序引用
Microsoft.Practices.ServiceLocation:依赖注入机制的服务本地化程序集。该程序集能够通过为依赖注入提供抽象层整合任何适合的依赖注入容器。
Systems.Windows.interactivity:事件,交互
【安装完MVVMLight之后的文件结构】
App.Xaml
【依赖注入】
App.Xaml中使用了ViewModelLocator进行依赖注入,代码如下:
1 /*
2 In App.xaml:
3
4
6
7
8 In the View:
9 DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
10
11 You can also use Blend to do all this with the tool's support.
12 See http://www.galasoft.ch/mvvm
13 */
14
15 using ClientService.Implements;
16 using ClientService.Interfaces;
17 using GalaSoft.MvvmLight.Ioc;
18 using Microsoft.Practices.ServiceLocation;
19
20 namespace MVVMLight.Shell.ViewModel
21 {
22 ///
23 /// This class contains static references to all the view models in the
24 /// application and provides an entry point for the bindings.
25 ///
26 public class ViewModelLocator
27 {
28
29 #region 构造函数
30
31 ///
32 /// Initializes a new instance of the ViewModelLocator class.
33 ///
34 public ViewModelLocator()
35 {
36 INavigationService navigationService = null;
37
38 /// 参数是返回值为IServiceLocator的委托
39 ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
40
41 ////if (ViewModelBase.IsInDesignModeStatic)
42 ////{
43 //// // Create design time view services and models
44 //// SimpleIoc.Default.Register();
45 ////}
46 ////else
47 ////{
48 //// // Create run time view services and models
49 //// SimpleIoc.Default.Register();
50 ////}
51
52 //这种写法有问题,App.RootFrame会在Application_Launching方法执行完成之后有值
53 //navigationService = new PhoneNavigationService(App.RootFrame);
54 //SimpleIoc.Default.Register(() =>
55 // new MainViewModel(navigationService), false);
56
57 // 方法执行顺序:
58 // 1.App构造函数
59 // 2.ViewModelLocator构造函数(App.xaml中的资源添加了ViewModelLocator)
60 // 3.App的Application_Launching方法
61 // 4.Navigate方法(App.RootFrame不为空)
62 // 5.取得对应的ViewModel(MainViewModel),执行对应的依赖注入的委托
63 // 正确写法,不立即注入(默认值)
64 // 此处每个ViewModel中的navigationService相同(可考虑改进,适合使用单例模式)
65 SimpleIoc.Default.Register(() =>
66 new MainViewModel(navigationService = new PhoneNavigationService(App.RootFrame)), false);
67
68 SimpleIoc.Default.Register(() =>
69 new Page1ViewModel(navigationService), false);
70 }
71
72 #endregion
73
74 public MainViewModel Main
75 {
76 get
77 {
78 return ServiceLocator.Current.GetInstance();
79 }
80 }
81
82 public Page1ViewModel Page1
83 {
84 get
85 {
86 return SimpleIoc.Default.GetInstance();
87 }
88 }
89
90 public static void Cleanup()
91 {
92 // TODO Clear the ViewModels
93 }
94 }
95 }
ViewModelLocator
【Appbar绑定Command】
使用第三方组件AppBarUtils 命令绑定
View Code
【创建动态磁贴ShellTile】
参考文章:与众不同 windows phone (8) - Tile(磁贴)
///
/// 创建磁贴
///
public ICommand CreateTileCommand
{
get
{
return new RelayCommand(() =>
{
if (ShellTile.ActiveTiles.Where(item => item.NavigationUri.OriginalString == "/Views/Page2.xaml?DeepLink=true").Count() > 0)
{
MessageBox.Show("已经添加了磁贴");
return;
}
StandardTileData newTile = new StandardTileData
{
Title = "Page2次要磁贴",
//BackgroundImage = new Uri("TileBackgroundBlue.png", UriKind.Relative),
Count = 2,
BackTitle = "App Back Tile Title",
//BackBackgroundImage = new Uri("TileBackgroundGreen.png", UriKind.Relative),
BackContent = "App Back Tile Content" + Environment.NewLine + "OK"
};
//shellTileService.Update(newTile);
ShellTile.Create(new Uri("/Views/Page2.xaml?DeepLink=true", UriKind.Relative), newTile);
});
}
}
///
/// 删除磁贴
///
public ICommand DeleteTileCommand
{
get
{
return new RelayCommand(() =>
{
var shellTile = ShellTile.ActiveTiles.First(item => item.NavigationUri.OriginalString == "/Views/Page2.xaml?DeepLink=true");
shellTile.Delete();
});
}
}
View Code
【导航Navigate】
使用适配器模式,重新封装本地的一些服务,以提供统一的访问接口(如导航INavigationService)
【快速恢复FastResume】
参考文章:Windows phone 8 Fast Resume 快速恢复浅析(一)
程序清单文件中设置激活方式为Resume
View Code 在App.xaml.cs文件中,注册RootFrame.Navigating事件,以进行快速恢复的相关处理:
///
/// 快速恢复
///
///
///
void FastResume(object sender, NavigatingCancelEventArgs e)
{
if (e.NavigationMode == NavigationMode.Reset)
{
isResume = true;
return;
}
if (isResume && e.NavigationMode == NavigationMode.New)
{
isResume = false;
if (!e.Uri.ToString().Contains("DeepLink=true"))
{
e.Cancel = true;
}
}
}
View Code
【独立存储】
参考:Windows Phone 独立存储之IsolatedStorageSettings
【墓碑恢复】
Windows Phone 应用程序生命周期
1 using Microsoft.Phone.Controls;
2 using System.Windows.Navigation;
3
4 namespace PhoneClient.Adapters.Interfaces
5 {
6 public interface INavigationService
7 {
8 #region 属性
9
10 PhoneApplicationFrame Frame
11 {
12 get;
13 }
14
15 #endregion
16
17 #region 事件
18
19 event NavigatedEventHandler Navigated;
20 event NavigatingCancelEventHandler Navigating;
21
22 #endregion
23
24 #region 方法
25
26 void NavigateTo(string url);
27
28 #endregion
29 }
30 }
INavigationService.cs
1 using System;
2 using System.Windows.Navigation;
3
4 using Microsoft.Phone.Controls;
5 using PhoneClient.Adapters.Interfaces;
6
7 namespace PhoneClient.Adapters.Implements
8 {
9 public class NavigationServiceAdapter : INavigationService
10 {
11 #region 字段
12
13 private PhoneApplicationFrame frame;
14
15 #endregion
16
17 #region 事件
18
19 public event NavigatedEventHandler Navigated;
20 public event NavigatingCancelEventHandler Navigating;
21
22 #endregion
23
24 #region 构造函数
25
26 public NavigationServiceAdapter(PhoneApplicationFrame frame)
27 {
28 this.frame = frame;
29 this.frame.Navigating += frame_Navigating;
30 this.frame.Navigated += frame_Navigated;
31 }
32
33 #endregion
34
35 #region 方法
36
37 void INavigationService.NavigateTo(string url)
38 {
39 if (this.frame != null)
40 {
41 this.frame.Navigate(new Uri(url, UriKind.Relative));
42 }
43 }
44
45 void frame_Navigating(object sender, NavigatingCancelEventArgs e)
46 {
47 if (Navigating != null)
48 {
49 Navigating(sender, e);
50 }
51 }
52
53 void frame_Navigated(object sender, NavigationEventArgs e)
54 {
55 if (Navigated != null)
56 {
57 Navigated(sender, e);
58 }
59 }
60
61 #endregion
62
63 PhoneApplicationFrame INavigationService.Frame
64 {
65 get
66 {
67 return frame;
68 }
69 }
70 }
71 }
NavigationServiceAdapter
1 using System.Linq;
2
3 using GalaSoft.MvvmLight;
4 using MVVMLight.Shell.Common.StorageHelper;
5 using PhoneClient.Adapters.Interfaces;
6 using System;
7
8 namespace MVVMLight.Shell.ViewModels
9 {
10 public class ViewModel : ViewModelBase
11 {
12 #region 字段
13
14 private INavigationService navigationService;
15
16 private Uri pageUri;
17
18 #endregion
19
20 #region 构造方法
21
22 public ViewModel(INavigationService navigationService, Uri pageUri)
23 {
24 if (navigationService != null)
25 {
26 this.navigationService = navigationService;
27 this.pageUri = pageUri;
28 this.navigationService.Navigating += navigationService_Navigating;
29 this.navigationService.Navigated += navigationService_Navigated;
30 }
31 }
32
33 #endregion
34
35 #region 私有方法
36
37 private void navigationService_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
38 {
39 // 保存程序状态
40 if (e.Uri.OriginalString == "app://external/")
41 {
42 OnPageDeactivation();
43 IsolatedStorageHelper.SettingSave("tombstone", true);
44 }
45 }
46
47 private void navigationService_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
48 {
49 // 墓碑恢复
50 if (e.Uri.OriginalString != "app://external/" && IsolatedStorageHelper.SettingLoad("tombstone") == true)
51 {
52 OnPageResumeFromTombstone();
53
54 // 所有页面都从墓碑状态恢复之后删除独立存储中的墓碑标识
55 if (this.navigationService.Frame.BackStack.Count() == 0)
56 {
57 IsolatedStorageHelper.SettingRemove("tombstone");
58 }
59 }
60
61 // 判断当前导航的页面与ViewModel是否对应
62 if (this.pageUri.OriginalString == e.Uri.OriginalString)
63 {
64 OnNavigatedTo();
65 }
66 }
67
68 #endregion
69
70 #region 方法
71
72 public virtual void OnPageDeactivation()
73 {
74
75 }
76
77 public virtual void OnPageResumeFromTombstone()
78 {
79
80 }
81
82 public virtual void OnNavigatedTo()
83 {
84
85 }
86
87 #endregion
88
89 }
90 }
ViewModel
页:
[1]