Puh – getting dizzy by all the environments?
Luckily once you have the initial project set up they all behave the same from a model perspective.
This article focus on the ability to store data locally on the device. To store on server you use a PersistenceMapperWCFClient.
To store on the client the recommendation is to use a PersistenceMapperXml.
The file system and ways to keep settings are however different per platform.
In this example I create a HubApp solution with one Windows Phone Silverlight 8.1 app.
I make use of the Eco.Handles.PortableCL, Eco.Interfaces.PortableCL, Eco.LinqExtender.PortableCL assemblies of MDriven.
I also have a Windows 8.1 (Store) application that use the same MDriven Assemblies.
Note that both projects also use an assembly called ClassLibrary1.
This is a Portable class library that also make use of the same MDriven assemblies and I use it for the Model and for the EcoSpace:
I added the EcoSpace and Model to this project by copying them from a non Portable project created via the template.
The model looks like this (standard template):
and there is a ViewModel defined like this (standard template, with codegen checked):
The EcoSpace has the persistenceMapper set up like this:
private void InitializeComponent() { this.persistenceMapperXml1 = new Eco.Persistence.PersistenceMapperXml(); this.persistenceMapperXml1.FileName = "SomeUniqueName"; this.PersistenceMapper = this.persistenceMapperXml1; }
Starting with Windows Phone
On the Page I want to show MDriven data on I do this:
When the page is entered:
protected override void OnNavigatedTo(NavigationEventArgs e)
We want to set things up:
_es = new EcoProject1EcoSpace(); _es.persistenceMapperXml1.OnLoadAsXML += persistenceMapperXml1_OnLoadAsXML; _es.persistenceMapperXml1.OnSaveAsXML += persistenceMapperXml1_OnSaveAsXML; _es.Active = true;
We create the EcoSpace.
We hook the PeristenceMapperXml OnLoadAsXML and OnSaveAsXML.
We then set the EcoSpace to Active.
In order to use MDriven ViewModels we also init like this:
PortableDequeuer.Active = true; ViewModelDefinitionsInApplication.Init(_es); SampleViewModel x = SampleViewModel.Create(_es, null); TheGrid.DataContext = x;
The LoadAsXml we implement like this:
void persistenceMapperXml1_OnLoadAsXML(object sender, Eco.Persistence.OnLoadAsXMLArgs e) { var applicationData = Windows.Storage.ApplicationData.Current; string data = applicationData.LocalSettings.Values[e.FileName] as string; e.LoadedDataAsXml = data; }
In this code we grab the xml string from the setting and that is enough for MDriven to know what to do.
When we later leave the page we end up here:
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { base.OnNavigatingFrom(e); _es.UpdateDatabase(); _es.Active = false; }
I added code to save. The UpdateDatabase will use the PersistenceMapperXml and that will call our implementation of OnSaveAsXml that looks like this:
void persistenceMapperXml1_OnSaveAsXML(object sender, Eco.Persistence.OnSaveAsXMLArgs e) { var applicationData = Windows.Storage.ApplicationData.Current; applicationData.LocalSettings.Values[e.FileName] = e.XDocumentToSave.ToString(); }
To make the sample show something I added this Xaml to the page:
<phone:PhoneApplicationPage.Resources> <DataTemplate x:Key="OneItem"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Hello"></TextBlock> <TextBox Text="{Binding Attribute1,Mode=TwoWay}"></TextBox> </StackPanel> </DataTemplate> </phone:PhoneApplicationPage.Resources>
<StackPanel Grid.Row="1" x:Name="TheGrid"> <Button Click="Button_Click">Press me</Button> <ItemsControl ItemsSource="{Binding AllInstances}"
ItemTemplate="{StaticResource OneItem}"></ItemsControl> </StackPanel>
The Button_Click does this:
private void Button_Click(object sender, RoutedEventArgs e) { var c1 = new Class1(_es); }
When I run I get this:
When I leave by pressing <- arrow back on the phone data is saved, and enter the page data is loaded.
Windows Store 8.1
The code is very similar:
protected override void OnNavigatedTo(NavigationEventArgs e) { this.navigationHelper.OnNavigatedTo(e); _es = new EcoProject1EcoSpace(); _es.persistenceMapperXml1.OnLoadAsXML += persistenceMapperXml1_OnLoadAsXML; _es.persistenceMapperXml1.OnSaveAsXML += persistenceMapperXml1_OnSaveAsXML; _es.Active = true; PortableDequeuer.Active = true; ViewModelDefinitionsInApplication.Init(_es); SampleViewModel x = SampleViewModel.Create(_es, null); TheGrid.DataContext = x; } protected override void OnNavigatedFrom(NavigationEventArgs e) { this.navigationHelper.OnNavigatedFrom(e); _es.UpdateDatabase(); _es.Active = false; } void persistenceMapperXml1_OnSaveAsXML(object sender, Eco.Persistence.OnSaveAsXMLArgs e) { var applicationData = Windows.Storage.ApplicationData.Current; applicationData.LocalSettings.Values[e.FileName] = e.XDocumentToSave.ToString(); } void persistenceMapperXml1_OnLoadAsXML(object sender, Eco.Persistence.OnLoadAsXMLArgs e) { var applicationData = Windows.Storage.ApplicationData.Current; string data = applicationData.LocalSettings.Values[e.FileName] as string; e.LoadedDataAsXml = data; } private void Button_Click(object sender, RoutedEventArgs e) { var c1 = new Class1(_es); }
The Xaml as well:
<Page.Resources> <DataTemplate x:Key="OneItem"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Hello"></TextBlock> <TextBox Text="{Binding Attribute1,Mode=TwoWay}"></TextBox> </StackPanel> </DataTemplate> </Page.Resources>
<StackPanel Grid.Row="1" x:Name="TheGrid"> <Button Click="Button_Click">Press me</Button> <ItemsControl ItemsSource="{Binding AllInstances}"
ItemTemplate="{StaticResource OneItem}"></ItemsControl> </StackPanel>
The result:
And this too loads when opened and saves when left.
2 Responses to Storing locally on the Windows Phone 8.1 and WindowsStore 8.1–and in Xamarin