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.Controls;
using Microsoft.Phone.Shell; using Microsoft.Phone.Shell;
using MyFriendsAround.WP7.ViewModel; using MyFriendsAround.WP7.ViewModel;
using MyFriendsAround.WP7.Utils;
namespace MyFriendsAround.WP7 namespace MyFriendsAround.WP7
{ {
@@ -43,28 +45,63 @@ namespace MyFriendsAround.WP7
// This code will not execute when the application is reactivated // This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e) private void Application_Launching(object sender, LaunchingEventArgs e)
{ {
LoadModel();
} }
// Code to execute when the application is activated (brought to foreground) // Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched // This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e) private void Application_Activated(object sender, ActivatedEventArgs e)
{ {
LoadModel();
} }
// Code to execute when the application is deactivated (sent to background) // Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing // This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e) private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{ {
SaveModel();
} }
// Code to execute when the application is closing (eg, user hit Back) // Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated // This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e) private void Application_Closing(object sender, ClosingEventArgs e)
{ {
SaveModel();
//
ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>(); ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>();
locator.Cleanup(); 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 // Code to execute if a navigation fails
void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{ {
@@ -85,6 +122,7 @@ namespace MyFriendsAround.WP7
} }
} }
#region Phone application initialization #region Phone application initialization
// Avoid double-initialization // Avoid double-initialization
@@ -118,6 +118,7 @@
</Compile> </Compile>
<Compile Include="Helpers\Navigation\IPageNavigation.cs" /> <Compile Include="Helpers\Navigation\IPageNavigation.cs" />
<Compile Include="Helpers\Navigation\PageNavigation.cs" /> <Compile Include="Helpers\Navigation\PageNavigation.cs" />
<Compile Include="Utils\ApplicationExtensions.cs" />
<Compile Include="Views\AboutPage.xaml.cs"> <Compile Include="Views\AboutPage.xaml.cs">
<DependentUpon>AboutPage.xaml</DependentUpon> <DependentUpon>AboutPage.xaml</DependentUpon>
</Compile> </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 { public string AppBarTextAbout {
get { return "About"; } get { return "About"; }
@@ -74,8 +74,6 @@ namespace MyFriendsAround.WP7.ViewModel
// Create run time view models // Create run time view models
} }
Container.Instance.RegisterInstance(typeof(MainViewModel), "MainViewModel");
Container.Instance.RegisterInstance(typeof(AboutViewModel), "AboutViewModel");
} }
/// <summary> /// <summary>
@@ -85,7 +83,7 @@ namespace MyFriendsAround.WP7.ViewModel
{ {
get get
{ {
MainViewModel mainViewModel = GetViewModel<MainViewModel>(); MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
return mainViewModel; return mainViewModel;
} }
} }
@@ -97,7 +95,7 @@ namespace MyFriendsAround.WP7.ViewModel
{ {
get get
{ {
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>(); AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>("AboutViewModel");
return aboutViewModel; return aboutViewModel;
} }
} }
@@ -108,9 +106,9 @@ namespace MyFriendsAround.WP7.ViewModel
/// </summary> /// </summary>
public void Cleanup() public void Cleanup()
{ {
MainViewModel mainViewModel = GetViewModel<MainViewModel>(); MainViewModel mainViewModel = GetViewModel<MainViewModel>("MainViewModel");
mainViewModel.Cleanup(); mainViewModel.Cleanup();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>(); AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>("AboutViewModel");
aboutViewModel.Cleanup(); aboutViewModel.Cleanup();
} }
@@ -118,10 +116,10 @@ namespace MyFriendsAround.WP7.ViewModel
#region Local Helpers #region Local Helpers
private T GetViewModel<T>() where T : ViewModelBase private T GetViewModel<T>(string key) where T : ViewModelBase
{ {
// Create a new view model // 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 //Assign the Context from PageNavigation to Context property of the ViewModelBase
vm.Context = vm.PageNav.CurrentContext; 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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 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}" FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}" Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" SupportedOrientations="Portrait"
@@ -14,15 +18,17 @@
d:DesignHeight="768" d:DesignHeight="768"
shell:SystemTray.IsVisible="True" shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}" 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> <phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="PushpinControlTemplate1" <ControlTemplate x:Key="PushpinControlTemplate1"
TargetType="my:Pushpin"> TargetType="my:Pushpin">
<Grid Height="32" <Grid Height="32"
Width="32" Margin="-16,-16,0,0"> Width="32"
Margin="-16,-16,0,0">
<Ellipse Fill="#FFA3A3BE" <Ellipse Fill="#FFA3A3BE"
Stroke="Black" Stroke="Black"
Margin="0" /> Margin="0" />
@@ -32,25 +38,28 @@
</phone:PhoneApplicationPage.Resources> </phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" <Grid x:Name="LayoutRoot"
Background="Transparent"> Background="Transparent">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title--> <!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" <StackPanel x:Name="TitlePanel"
Grid.Row="0" Grid.Row="0"
Margin="24,24,0,12"> Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle" <TextBlock x:Name="ApplicationTitle"
Text="{Binding ApplicationTitle}" Text="{Binding ApplicationTitle}"
Style="{StaticResource PhoneTextNormalStyle}" /> Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle" Text="{Binding PageName}" Margin="-3,-8,0,0" Style="{StaticResource PhoneTextTitle1Style}" /> <TextBlock x:Name="PageTitle"
Text="{Binding PageName}"
Margin="-3,-8,0,0"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel> </StackPanel>
<!--ContentPanel - place additional content here--> <!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid" <Grid x:Name="ContentGrid"
Grid.Row="1" Grid.Row="1"
Margin="0,0,0,70"> Margin="0,0,0,70">
<!--<Button Content="Publish" <!--<Button Content="Publish"
@@ -65,7 +74,13 @@
</i:Interaction.Triggers> </i:Interaction.Triggers>
</Button>--> </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" <my:Map x:Name="map"
Height="468" Height="468"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -73,12 +88,11 @@
VerticalAlignment="Top" VerticalAlignment="Top"
Width="468" Width="468"
Center="{Binding Path=MapCenter, Mode=TwoWay}"> Center="{Binding Path=MapCenter, Mode=TwoWay}">
<my:MapItemsControl ItemsSource="{Binding PushPins}" <my:MapItemsControl ItemsSource="{Binding PushPins}">
>
<my:MapItemsControl.ItemTemplate> <my:MapItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<my:Pushpin Location="{Binding Location}" <my:Pushpin Location="{Binding Location}"
Template="{StaticResource PushpinControlTemplate1}"> Template="{StaticResource PushpinControlTemplate1}">
</my:Pushpin> </my:Pushpin>
</DataTemplate> </DataTemplate>
</my:MapItemsControl.ItemTemplate> </my:MapItemsControl.ItemTemplate>
@@ -102,15 +116,15 @@
<Preview:BindableApplicationBarIconButton Command="{Binding NavigateToAboutCommand}" <Preview:BindableApplicationBarIconButton Command="{Binding NavigateToAboutCommand}"
IconUri="/icons/appbar.questionmark.rest.png" IconUri="/icons/appbar.questionmark.rest.png"
Text="{Binding AppBarTextAbout}" /> Text="{Binding AppBarTextAbout}" />
<Preview:BindableApplicationBar.MenuItems> <Preview:BindableApplicationBar.MenuItems>
<Preview:BindableApplicationBarMenuItem Text="Settings" <Preview:BindableApplicationBarMenuItem Text="Settings"
Command="{Binding InputBoxCommand}" /> Command="{Binding InputBoxCommand}" />
</Preview:BindableApplicationBar.MenuItems> </Preview:BindableApplicationBar.MenuItems>
</Preview:BindableApplicationBar> </Preview:BindableApplicationBar>
</Grid> </Grid>
<!-- Sample code showing usage of ApplicationBar <!-- Sample code showing usage of ApplicationBar
<phone:PhoneApplicationPage.ApplicationBar> <phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton x:Name="appbar_button1" IconUri="/Images/appbar_button1.png" Text="Button 1"></shell:ApplicationBarIconButton> <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.ApplicationBar>
--> -->
</phone:PhoneApplicationPage> </phone:PhoneApplicationPage>