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.
