Silverlight: Saving window position and size

Something I've done many a time in WinForms is to write a small class or extension method which I can attach to a form to persist its size and position. I wanted to do the same thing in my Silverlight out-of-browser application and it turned out a little trickier than I thought.

Persisting

In the WinForms version, I'd normally attach to the resize and move events, but I couldn't find the equivalent in Silverlight so just added the saving in the App.Exit event:

private void SaveApplicationSize()
{
  var xml = new XDocument(
    new XElement("WindowInfo",
      new XElement("MainWindow",
        new XAttribute("IsMaximized", MainWindow.WindowState == WindowState.Maximized),
        new XAttribute("Width", MainWindow.Width),
        new XAttribute("Height", MainWindow.Height),
        new XAttribute("Top", MainWindow.Top),
        new XAttribute("Left", MainWindow.Left)
      )
    )
  );
  using (var store = IsolatedStorageFile.GetUserStoreForApplication())
  using (var library = store.OpenFile("window-settings.xml", FileMode.Create))
    xml.Save(library);
}

Restoring

Then, in the App.Startup event, after setting the RootVisual, it's just a matter of pulling back the data from isolated storage and setting the size/position accordingly:

using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
  if (!store.FileExists("window-settings.xml")) return;

  using (var windowInfo = store.OpenFile("window-settings.xml", FileMode.Open))
  {
    var posAndSize = XDocument.Load(windowInfo).Descendants("MainWindow").FirstOrDefault();
    if (posAndSize == null) return;

    if (bool.Parse(posAndSize.Attribute("IsMaximized").Value))
                    MainWindow.WindowState = WindowState.Maximized;
    else
    {
      MainWindow.Width = int.Parse(posAndSize.Attribute("Width").Value);
      MainWindow.Height = int.Parse(posAndSize.Attribute("Height").Value);
      MainWindow.Top = int.Parse(posAndSize.Attribute("Top").Value);
      MainWindow.Left = int.Parse(posAndSize.Attribute("Left").Value);
    }
  }
}

This is just the basic idea. For example, if the user's resolution changes, it may attempt to restore the application to a value that is too large, in which case Silverlight throws an error. In the WinForms world, I usually check the screen size and adjusted as necessary, but again, I couldn't find the analogous in Silverlight. There are the Host.Content.ActualHeight and Host.Content.ActualWidth properties that I thought might be the screen resolution for an out-of-browser app, but this doesn't appear to be the case. So for the moment, I'm simply catching any exception while setting the size/position and ignoring it - therefore the application shows in the default size and position.


Comments:

http://www.pitorque.de/MisterGoodcat/post/Determine-screen-resolution-in-Silverlight-OOB.aspx


Comment Guidelines
See the FAQ for details on the full rules and guidelines. No Spam. Write clearly and thoughtfully - no bad language.