Welcome to WindowsClient.net | My Blog | Sign in | Join

Rob Relyea - XAMLified

WPF, Silverlight and XAML

Syndication

Sponsors





  • advertise here
Persistable View Models & XAML for Config

I’m working on a XamlPad application sample using WPF4. As part of that, I’m ending up exploring ideas around persistable view models, which may end up having a lot to do with Xaml for Config.

 image

Here is the current persisted view model for my application, which you may be able to guess can open several files at one time. I happen to display them with a tabcontrol. When you close the application, it saves the window location, all the documents I had open, what mode I was viewing them in, and the position of the splitter for each.

Here is the config.xaml file for this application:

 

  1. <XamlPadConfig ActiveXamlDocument="1" WindowHeight="640" WindowLeft="1692" WindowTop="169" WindowWidth="837" xmlns="clr-namespace:XamlPadHelpers;assembly=XamlPadHelpers">
  2.   <XamlDocumentViewModel BottomRowHeight="1027*" TopRowHeight="116*">
  3.     <XamlDocument FileName="C:\Users\rrelyea\AppData\Local\Temp\temp.xaml" />
  4.   </XamlDocumentViewModel>
  5.   <XamlDocumentViewModel BottomRowHeight="330*" TopRowHeight="237*" XamlViewState="Xaml">
  6.     <XamlDocument FileName="C:\Users\rrelyea\AppData\Local\Temp\temp2.xaml" />
  7.   </XamlDocumentViewModel>
  8.   <XamlDocumentViewModel BottomRowHeight="344*" TopRowHeight="223*" XamlViewState="View">
  9.     <XamlDocument FileName="C:\Users\rrelyea\Documents\doc.xaml" />
  10.   </XamlDocumentViewModel>
  11.   <XamlDocumentViewModel BottomRowHeight="*" TopRowHeight="2*">
  12.     <XamlDocument FileName="C:\Users\rrelyea\Documents\Visual Studio 2010\Projects\XamlDesigner\XamlDesigner\ProjectExplorer.xaml" />
  13.   </XamlDocumentViewModel>
  14. </XamlPadConfig>

 

Here is my mainwindow ctor(). It loads the config file before loading MainWindow.xaml (which has bindings to config data):

  1.         public MainWindow()
  2.         {
  3.             xamlPadConfig = GetConfigData();
  4.             DataContext = xamlPadConfig;
  5.             InitializeComponent();
  6.             this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
  7.         }

Here is a routine that loads the config file or provides a set of defaults. (these defaults could be specified as a separate XAML file that I embed in the .exe if I wanted.)

  1.         private XamlPadConfig GetConfigData()
  2.         {
  3.             XamlPadConfig configData = null;
  4.             configFile = System.Environment.CurrentDirectory + "\\config.xaml";
  5.             if (File.Exists(configFile))
  6.             {
  7.                 try
  8.                 {
  9.                     configData = (XamlPadConfig)XamlServices.Load(configFile);
  10.                 }
  11.                 catch (Exception)
  12.                 {
  13.                     //problem with settings file, ignore it, eventually replace it
  14.                 }
  15.             }
  16.             if (configData == null)
  17.             {
  18.                 configData = new XamlPadConfig()
  19.                 {
  20.                     WindowHeight = 400,
  21.                     WindowWidth = 600,
  22.                     XamlDocumentViewModels = {                    
  23.                         CreateDefaultXamlDocumentViewModel(Environment.GetEnvironmentVariable("temp") + "\\temp.xaml")
  24.                     }
  25.                 };
  26.             }
  27.             return configData;
  28.         }

Here is a routine which creates a new XamlDocumentViewModel given a file location. For new files with no location yet, I end up passing in null.

  1.         private static XamlDocumentViewModel CreateDefaultXamlDocumentViewModel(string fileName)
  2.         {
  3.             return new XamlDocumentViewModel()
  4.             {
  5.                 XamlViewState = XamlPadHelpers.XamlViewState.Split,
  6.                 XamlDocument = new XamlDocument()
  7.                 {
  8.                     FileName = fileName,
  9.                 },
  10.                 TopRowHeight = new GridLength(2, GridUnitType.Star),
  11.                 BottomRowHeight = new GridLength(1, GridUnitType.Star)
  12.             };
  13.         }

Here is a routine which runs when the window is closed and saves that config.

  1.         void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  2.         {
  3.             XamlServices.Save(configFile, xamlPadConfig);
  4.         }

Here is my current MainWindow.xaml:

  1. <Window x:Class="XamlPadSample.MainWindow"
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:xph="clr-namespace:XamlPadHelpers;assembly=XamlPadHelpers"
  5.         Title="XamlPad Sample"
  6.         Height="{Binding WindowHeight, Mode=TwoWay}"
  7.         Width="{Binding WindowWidth, Mode=TwoWay}"
  8.         Top="{Binding WindowTop, Mode=TwoWay}"
  9.         Left="{Binding WindowLeft, Mode=TwoWay}"
  10.         >
  11.     <Grid>
  12.         <Grid.ColumnDefinitions>
  13.             <ColumnDefinition Width="20" />
  14.             <ColumnDefinition Width="*" />
  15.         </Grid.ColumnDefinitions>
  16.         <StackPanel Orientation="Horizontal" Grid.Column="0">
  17.             <StackPanel.LayoutTransform>
  18.                 <RotateTransform Angle="90" />
  19.             </StackPanel.LayoutTransform>
  20.             <Button Click="New">New</Button>
  21.             <Button Click="Open">Open</Button>
  22.             <Button Click="Save">Save</Button>
  23.             <Button>Exit</Button>
  24.         </StackPanel>
  25.         <TabControl ItemsSource="{Binding XamlDocumentViewModels}"
  26.                     SelectedIndex="{Binding ActiveXamlDocument}" Name="documentsTabControl"
  27.                     Grid.Column="1"
  28.                     >
  29.             <TabControl.ItemTemplate>
  30.                 <DataTemplate DataType="{x:Type xph:XamlDocumentViewModel}">
  31.                     <StackPanel Orientation="Horizontal">
  32.                         <StackPanel.ToolTip>
  33.                             <TextBlock Text="{Binding XamlDocument.FileName}" />
  34.                         </StackPanel.ToolTip>
  35.                         <TextBlock Text="{Binding XamlDocument.FileNameShort}"/>
  36.                         <TextBlock Text="{Binding XamlDocument.DirtyString}" />
  37.                     </StackPanel>
  38.                 </DataTemplate>
  39.             </TabControl.ItemTemplate>
  40.             <TabControl.ContentTemplate>
  41.                 <DataTemplate DataType="{x:Type xph:XamlDocumentViewModel}" >
  42.                     <xph:XamlPad x:Name="xamlPad" />
  43.                 </DataTemplate>
  44.             </TabControl.ContentTemplate>
  45.         </TabControl>
  46.     </Grid>
  47. </Window>

I’ll likely post this complete example soon. This was fun to build and sends my mind in several directions on possibilities.

I’m curious how many of you are trying to save and load your view models?

Published Saturday, January 16, 2010 7:41 AM by Rob_Relyea

Comments

# Dew Drop &#8211; January 17, 2010 | Alvin Ashcraft&#039;s Morning Dew@ Sunday, January 17, 2010 9:48 AM

Pingback from  Dew Drop &#8211; January 17, 2010 | Alvin Ashcraft&#039;s Morning Dew

# re: Persistable View Models & XAML for Config@ Sunday, January 17, 2010 11:19 AM

That's interesting, because I hadn't really tackled it as saving my view model before. To me, the view model contains a subset of models and services, so each service is responsible for understanding the persistance of the model it exposes. Therefore, if you leave and come back, when the view model is created fresh, and begins calling services, the services supply the models and then the bindings restore the saved state. This is interesting, however, because that pattern doesn't accomodate UI state or some of the preferences that exist in the client. Looking forward to the follow-up posts!

# Links (1/17/2010) &laquo; Steve Pietrek-Everything SharePoint/Silverlight@ Sunday, January 17, 2010 7:40 PM

Pingback from  Links (1/17/2010) &laquo; Steve Pietrek-Everything SharePoint/Silverlight

# XamlPadSample – Step 1@ Wednesday, January 20, 2010 12:15 PM

XamlPadSample step 1 sample code is now available for download from robrelyea.com/.../XamlPadSample

# Windows Client Developer Roundup for 1/25/2010@ Monday, January 25, 2010 1:56 AM

This is Windows Client Developer roundup #8. I’m off in Reykjavik Iceland this week, speaking about Silverlight

# Craig Sutherland: Considering XAML for Config for CruiseControl.NET@ Friday, February 12, 2010 4:02 AM

Interesting to see “From NetReflector to XAML” from Craig Sutherland detailing an exploration of using

# re: Persistable View Models & XAML for Config@ Friday, February 12, 2010 9:49 AM

Just and FYI for Rob; your formating of the C# code on a black background makes you posts unreadable in Google reader. I suppose it will either drive users to yyour site or ignore the post entirely.

# re: Persistable View Models & XAML for Config@ Friday, February 12, 2010 10:39 AM

@Lee-

Thanks for the heads up. I was having a hard time with Live Writer and the different code pasting addins that day.

-Rob

# Software should: adapt to users desired size/aspect ratio; crash less; remember user settings@ Tuesday, June 29, 2010 8:12 AM

Went back to my last blog (on http://rrelyea.spaces.live.com/blog ) to look at other entries in my Software

# XamlWriter.Save() for Silverlight@ Thursday, July 29, 2010 11:19 AM

I tweeted a pointer to David Poll’s “ To XAML with Love (an experiment with XAML Serialization in Silverlight

# Useful Links 475@ Sunday, March 04, 2012 11:36 PM

Useful Links 475

Leave a Comment

(required) 
(required) 
(optional)
(required)