tombstoning - saving and loadign from IsolateStorage

This commit is contained in:
2011-03-25 13:47:13 +02:00
parent f069ee7010
commit a25a7fb3fd
6 changed files with 173 additions and 38 deletions
+38
View File
@@ -13,6 +13,8 @@ using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using MyFriendsAround.WP7.ViewModel;
using MyFriendsAround.WP7.Utils;
namespace MyFriendsAround.WP7
{
@@ -43,28 +45,63 @@ namespace MyFriendsAround.WP7
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
LoadModel();
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
LoadModel();
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
SaveModel();
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
SaveModel();
//
ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>();
locator.Cleanup();
}
private void LoadModel()
{
MainViewModel mainModel = this.RetrieveFromIsolatedStorage<MainViewModel>();
if (mainModel != null)
{
Container.Instance.RegisterInstance<MainViewModel>(mainModel, "MainViewModel");
}
else
{
Container.Instance.RegisterInstance<MainViewModel>(new MainViewModel(), "MainViewModel");
}
AboutViewModel aboutModel = this.RetrieveFromIsolatedStorage<AboutViewModel>();
if (aboutModel != null)
{
Container.Instance.RegisterInstance<AboutViewModel>(aboutModel, "AboutViewModel");
}
else
{
Container.Instance.RegisterInstance<AboutViewModel>( new AboutViewModel(), "AboutViewModel");
}
}
private void SaveModel()
{
this.SaveToIsolatedStorage<MainViewModel>(Container.Instance.Resolve<MainViewModel>("MainViewModel"));
this.SaveToIsolatedStorage<AboutViewModel>(Container.Instance.Resolve<AboutViewModel>("AboutViewModel"));
}
// Code to execute if a navigation fails
void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
@@ -85,6 +122,7 @@ namespace MyFriendsAround.WP7
}
}
#region Phone application initialization
// Avoid double-initialization
@@ -118,6 +118,7 @@
</Compile>
<Compile Include="Helpers\Navigation\IPageNavigation.cs" />
<Compile Include="Helpers\Navigation\PageNavigation.cs" />
<Compile Include="Utils\ApplicationExtensions.cs" />
<Compile Include="Views\AboutPage.xaml.cs">
<DependentUpon>AboutPage.xaml</DependentUpon>
</Compile>
@@ -0,0 +1,60 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO.IsolatedStorage;
using System.IO;
using MyFriendsAround.WP7.ViewModel;
using System.Text;
namespace MyFriendsAround.WP7.Utils
{
public static class ApplicationExtensions
{
private static string GetIsFile(Type t)
{
return string.Concat(t.Name, ".dat");
}
public static T RetrieveFromIsolatedStorage<T>(this Application app) where T : class
{
using (var userAppStore = IsolatedStorageFile.GetUserStoreForApplication())
{
var dataFileName = GetIsFile(typeof(T));
if (userAppStore.FileExists(dataFileName))
{
using(StreamReader sr =new StreamReader(userAppStore.OpenFile(dataFileName, FileMode.Open), Encoding.UTF8))
{
return SerializationHelper.Deserialize<T>(sr.ReadToEnd());
}
}
}
return null;
}
public static void SaveToIsolatedStorage<T>(this Application app, T model) where T : class
{
var dataFileName = GetIsFile((model.GetType()));
using (var userAppStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (userAppStore.FileExists(dataFileName))
{
userAppStore.DeleteFile(dataFileName);
}
using (StreamWriter sw = new StreamWriter(userAppStore.CreateFile(dataFileName), Encoding.UTF8))
{
sw.Write(SerializationHelper.Serialize<T>(model));
}
}
}
}
}
@@ -171,7 +171,31 @@ namespace MyFriendsAround.WP7.ViewModel
}
public string MyName { get; set; }
/// <summary>
/// The <see cref="MyName" /> property's name.
/// </summary>
public const string MyNamePropertyName = "MyName";
private string _myName = "Guest";
/// <summary>
/// Gets the MyName property.
/// </summary>
public string MyName
{
get { return _myName; }
set
{
if (_myName == value)
{
return;
}
var oldValue = _myName;
_myName = value;
// Update bindings, no broadcast
RaisePropertyChanged(MyNamePropertyName);
}
}
public string AppBarTextAbout {
get { return "About"; }
@@ -74,8 +74,6 @@ namespace MyFriendsAround.WP7.ViewModel
// Create run time view models
}
Container.Instance.RegisterInstance(typeof(MainViewModel), "MainViewModel");
Container.Instance.RegisterInstance(typeof(AboutViewModel), "AboutViewModel");
}
/// <summary>
@@ -85,7 +83,7 @@ namespace MyFriendsAround.WP7.ViewModel
{
get
{
MainViewModel mainViewModel = GetViewModel<MainViewModel>();
MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
return mainViewModel;
}
}
@@ -97,7 +95,7 @@ namespace MyFriendsAround.WP7.ViewModel
{
get
{
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>("AboutViewModel");
return aboutViewModel;
}
}
@@ -108,9 +106,9 @@ namespace MyFriendsAround.WP7.ViewModel
/// </summary>
public void Cleanup()
{
MainViewModel mainViewModel = GetViewModel<MainViewModel>();
MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
mainViewModel.Cleanup();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>("AboutViewModel");
aboutViewModel.Cleanup();
}
@@ -118,10 +116,10 @@ namespace MyFriendsAround.WP7.ViewModel
#region Local Helpers
private T GetViewModel<T>() where T : ViewModelBase
private T GetViewModel<T>(string key) where T : ViewModelBase
{
// Create a new view model
T vm = Container.Instance.Resolve<T>();
T vm = Container.Instance.Resolve<T>(key);
//Assign the Context from PageNavigation to Context property of the ViewModelBase
vm.Context = vm.PageNav.CurrentContext;
+43 -29
View File
@@ -1,10 +1,14 @@
<phone:PhoneApplicationPage xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" x:Class="MyFriendsAround.WP7.MainPage"
<phone:PhoneApplicationPage xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
x:Class="MyFriendsAround.WP7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7" FontFamily="{StaticResource PhoneFontFamilyNormal}"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP7"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait"
@@ -14,15 +18,17 @@
d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}"
xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps" xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview">
xmlns:my="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
xmlns:Preview="clr-namespace:Phone7.Fx.Preview;assembly=Phone7.Fx.Preview">
<!--LayoutRoot contains the root grid where all other page content is placed-->
<!--LayoutRoot contains the root grid where all other page content is placed-->
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="PushpinControlTemplate1"
TargetType="my:Pushpin">
<Grid Height="32"
Width="32" Margin="-16,-16,0,0">
Width="32"
Margin="-16,-16,0,0">
<Ellipse Fill="#FFA3A3BE"
Stroke="Black"
Margin="0" />
@@ -32,25 +38,28 @@
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle"
Text="{Binding ApplicationTitle}"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle" Text="{Binding PageName}" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}" />
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle"
Text="{Binding ApplicationTitle}"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="{Binding PageName}"
Margin="-3,-8,0,0"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1"
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1"
Margin="0,0,0,70">
<!--<Button Content="Publish"
@@ -65,7 +74,13 @@
</i:Interaction.Triggers>
</Button>-->
<TextBox Height="67" HorizontalAlignment="Left" Margin="6,0,0,6" Name="txtMyName" Text="{Binding Path=MyName, Mode=TwoWay}" VerticalAlignment="Bottom" Width="468" />
<TextBox Height="67"
HorizontalAlignment="Left"
Margin="6,0,0,6"
Name="txtMyName"
Text="{Binding Path=MyName, Mode=TwoWay}"
VerticalAlignment="Bottom"
Width="468" />
<my:Map x:Name="map"
Height="468"
HorizontalAlignment="Left"
@@ -73,12 +88,11 @@
VerticalAlignment="Top"
Width="468"
Center="{Binding Path=MapCenter, Mode=TwoWay}">
<my:MapItemsControl ItemsSource="{Binding PushPins}"
>
<my:MapItemsControl ItemsSource="{Binding PushPins}">
<my:MapItemsControl.ItemTemplate>
<DataTemplate>
<my:Pushpin Location="{Binding Location}"
Template="{StaticResource PushpinControlTemplate1}">
Template="{StaticResource PushpinControlTemplate1}">
</my:Pushpin>
</DataTemplate>
</my:MapItemsControl.ItemTemplate>
@@ -102,15 +116,15 @@
<Preview:BindableApplicationBarIconButton Command="{Binding NavigateToAboutCommand}"
IconUri="/icons/appbar.questionmark.rest.png"
Text="{Binding AppBarTextAbout}" />
<Preview:BindableApplicationBar.MenuItems>
<Preview:BindableApplicationBarMenuItem Text="Settings"
Command="{Binding InputBoxCommand}" />
</Preview:BindableApplicationBar.MenuItems>
</Preview:BindableApplicationBar>
</Grid>
<!-- Sample code showing usage of ApplicationBar
<!-- Sample code showing usage of ApplicationBar
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton x:Name="appbar_button1" IconUri="/Images/appbar_button1.png" Text="Button 1"></shell:ApplicationBarIconButton>
@@ -123,6 +137,6 @@
</phone:PhoneApplicationPage.ApplicationBar>
-->
</phone:PhoneApplicationPage>