Today I am showing a simple implementation in WPF persisting window position, size, theme and layout. I am saving to xml and application settings.

I used Infragistics controls, but this could be the same code using either other vendor or WPF neat.

I have been trying to keep things as code based as possible, assuming if anyone have interest for details they would ask.

 

Here is the XAML

<igRibbon:XamRibbonWindow x:Class="HumanIdeas.GUI.Shell"
                          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                          xmlns:igRibbon="http://infragistics.com/Ribbon"
                          xmlns:igDock="http://infragistics.com/DockManager"
                          xmlns:Themes="clr-namespace:Infragistics.Windows.Themes;assembly=InfragisticsWPF3.v10.3"
                          xmlns:HI="http://schemas.HumanIdeas.com/HumanIdeas/windows"
                          MinHeight="600"
                          MinWidth="800"
                          FontFamily="Segoe UI"
                          HI:WindowSettings.Save="True"
                          Loaded="XamRibbonWindowLoaded"
                          Closed="XamRibbonWindowClosed"
                          >

    <igRibbon:XamRibbonWindow.Resources>
        <ResourceDictionary>
            <ObjectDataProvider x:Key="themeManager"
                                ObjectType="Themes:ThemeManager"
                                MethodName="GetThemes" />
        </ResourceDictionary>
    </igRibbon:XamRibbonWindow.Resources>

    <igRibbon:XamRibbonWindow.Title>
        <Binding Path="Title">
            <Binding.FallbackValue>Human Ideas</Binding.FallbackValue>
            <Binding.TargetNullValue>Human Ideas</Binding.TargetNullValue>
        </Binding>
    </igRibbon:XamRibbonWindow.Title>

    <igRibbon:RibbonWindowContentHost>

        <igRibbon:RibbonWindowContentHost.Ribbon>

            <igRibbon:XamRibbon Theme="{Binding ElementName=cboThemes, Path=SelectedValue, UpdateSourceTrigger=PropertyChanged}">
                <igRibbon:XamRibbon.ApplicationMenu>
                    <igRibbon:ApplicationMenu Caption="Layout">
                        <igRibbon:ApplicationMenu.Items>
                            
                            <StackPanel Orientation="Horizontal">
                                <TextBlock VerticalAlignment="Center"
                                           Text="Theme: " />
                                <ComboBox x:Name="cboThemes"
                                          VerticalAlignment="Center"
                                          IsEditable="False"
                                          
                                          MinWidth="100"
                                          SelectedIndex="0"
                                          ItemsSource="{Binding Source={StaticResource themeManager}}" />
                            </StackPanel>
                            
                            <Button Content="Reset Docking Layout"
                                    VerticalAlignment="Center"
                                    MinWidth="100"
                                    Click="ResetLayoutButtonClick" />

                        </igRibbon:ApplicationMenu.Items>
                    </igRibbon:ApplicationMenu>
                </igRibbon:XamRibbon.ApplicationMenu>

                <igRibbon:XamRibbon.Tabs>
                    <igRibbon:RibbonTabItem Header="Main">
                        <!--<igRibbon:RibbonGroup>
                        </igRibbon:RibbonGroup>-->
                    </igRibbon:RibbonTabItem>
                </igRibbon:XamRibbon.Tabs>
                
            </igRibbon:XamRibbon>

        </igRibbon:RibbonWindowContentHost.Ribbon>

        <igDock:XamDockManager x:Name="dockingManager"
                               Background="Transparent">
            <igDock:XamDockManager.Panes>
                <igDock:SplitPane x:Name="treePanel"
                                  igDock:XamDockManager.InitialLocation="DockedLeft">
                    <igDock:ContentPane x:Name="treePanelC"
                                        Background="Transparent"
                                        Header="Tree"
                                        AllowClose="False">

                    </igDock:ContentPane>
                </igDock:SplitPane>
                <igDock:SplitPane x:Name="summaryPanel"
                                  igDock:XamDockManager.InitialLocation="DockedTop">
                    <igDock:ContentPane x:Name="summaryPanelC"
                                        Background="Transparent"
                                        Header="Summary"
                                        AllowClose="False" />
                </igDock:SplitPane>
                <igDock:SplitPane x:Name="middlePanel"
                                  igDock:XamDockManager.InitialLocation="DockedTop">
                    <igDock:ContentPane x:Name="middlePanelC"
                                        Background="Transparent"
                                        Header="TBD"
                                        AllowClose="False" />
                </igDock:SplitPane>
                <igDock:SplitPane x:Name="ordersPanel"
                                  igDock:XamDockManager.InitialLocation="DockedTop">
                    <igDock:ContentPane  x:Name="ordersPanelC"
                                         Background="Transparent"
                                         Header="Orders"
                                         AllowClose="False" />
                </igDock:SplitPane>
            </igDock:XamDockManager.Panes>
        </igDock:XamDockManager>

        <igRibbon:RibbonWindowContentHost.StatusBar>
            <StatusBar>
                <TextBlock Text="Ready" />
            </StatusBar>
        </igRibbon:RibbonWindowContentHost.StatusBar>

    </igRibbon:RibbonWindowContentHost>

</igRibbon:XamRibbonWindow>

 

...and the code behind:

using System;
using System.IO;
using HumanIdeas.GUI.Properties;

namespace HumanIdeas.GUI
{
    /// <summary>
    /// Interaction logic for Shell.xaml
    /// </summary>
    public partial class Shell {
        private void ResetLayoutButtonClick(object sender, System.Windows.RoutedEventArgs e)
        {
            LoadDefaultLayout();
        }

        private void XamRibbonWindowLoaded(object sender, System.Windows.RoutedEventArgs e)
        {
            LoadLayout();
        }

        private void XamRibbonWindowClosed(object sender, EventArgs e)
        {
            SaveLayout();
        }        

        private void LoadDefaultLayout()
        {
            try
            {
                using (var fs = new FileStream(@"Data\defaultLayout.xml", FileMode.Open, FileAccess.Read))
                {
                    dockingManager.LoadLayout(fs);
                }

            }
            catch (FileNotFoundException)
            {
            }

        }

        private void LoadLayout()
        {
            var curTheme = Settings.Default.CurrentTheme;
            if (curTheme == null | curTheme == String.Empty)  cboThemes.SelectedIndex = 0;
            else cboThemes.SelectedValue = curTheme;

                try
                {
                    using (var fs = new FileStream(@"Data\layout.xml", FileMode.Open, FileAccess.Read))
                    {
                        dockingManager.LoadLayout(fs);
                    }

                }
                catch (FileNotFoundException)
                {
                    LoadDefaultLayout();
                }
        }

        private void SaveLayout()
        {
            Settings.Default.CurrentTheme = cboThemes.SelectedValue.ToString();
            Settings.Default.Save();

            using (var fs = new FileStream(@"Data\layout.xml", FileMode.Create, FileAccess.Write))
            {
                dockingManager.SaveLayout(fs);
            }

        }

    }
}