Skip to content

Commit

Permalink
Merge pull request #346 from punker76/customwindowsettings
Browse files Browse the repository at this point in the history
"save window settings elsewhere" scenario
  • Loading branch information
shiftbot committed Feb 15, 2013
2 parents 20f584d + e16154e commit 55ef43c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 60 deletions.
6 changes: 5 additions & 1 deletion MahApps.Metro/Behaviours/WindowsSettingBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ public class WindowsSettingBehaviour : Behavior<MetroWindow>
{
protected override void OnAttached()
{
WindowSettings.SetSave(AssociatedObject, AssociatedObject.SaveWindowPosition);
if (AssociatedObject != null && AssociatedObject.SaveWindowPosition) {
// save with custom settings class or use the default way
var windowPlacementSettings = this.AssociatedObject.WindowPlacementSettings ?? new WindowApplicationSettings(this.AssociatedObject);
WindowSettings.SetSave(AssociatedObject, windowPlacementSettings);
}
}
}
}
13 changes: 10 additions & 3 deletions MahApps.Metro/Controls/MetroWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public class MetroWindow : Window
public static readonly DependencyProperty ShowMaxRestoreButtonProperty = DependencyProperty.Register("ShowMaxRestoreButton", typeof(bool), typeof(MetroWindow), new PropertyMetadata(true));
public static readonly DependencyProperty TitlebarHeightProperty = DependencyProperty.Register("TitlebarHeight", typeof(int), typeof(MetroWindow), new PropertyMetadata(30));
public static readonly DependencyProperty TitleCapsProperty = DependencyProperty.Register("TitleCaps", typeof(bool), typeof(MetroWindow), new PropertyMetadata(true));
public static readonly DependencyProperty SavePositionProperty = DependencyProperty.Register("SaveWindowPosition", typeof(bool), typeof(MetroWindow), new PropertyMetadata(false));
public static readonly DependencyProperty SaveWindowPositionProperty = DependencyProperty.Register("SaveWindowPosition", typeof(bool), typeof(MetroWindow), new PropertyMetadata(false));
public static readonly DependencyProperty WindowPlacementSettingsProperty = DependencyProperty.Register("WindowPlacementSettings", typeof(IWindowPlacementSettings), typeof(MetroWindow), new PropertyMetadata(null));
public static readonly DependencyProperty TitleForegroundProperty = DependencyProperty.Register("TitleForeground", typeof(Brush), typeof(MetroWindow));
public static readonly DependencyProperty IgnoreTaskbarOnMaximizeProperty = DependencyProperty.Register("IgnoreTaskbar", typeof(bool), typeof(MetroWindow), new PropertyMetadata(false));

Expand All @@ -46,8 +47,14 @@ public Brush TitleForeground

public bool SaveWindowPosition
{
get { return (bool)GetValue(SavePositionProperty); }
set { SetValue(SavePositionProperty, value); }
get { return (bool)GetValue(SaveWindowPositionProperty); }
set { SetValue(SaveWindowPositionProperty, value); }
}

public IWindowPlacementSettings WindowPlacementSettings
{
get { return (IWindowPlacementSettings)GetValue(WindowPlacementSettingsProperty); }
set { SetValue(WindowPlacementSettingsProperty, value); }
}

public bool ShowIconOnTitleBar
Expand Down
101 changes: 49 additions & 52 deletions MahApps.Metro/Controls/WindowSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,74 @@

namespace MahApps.Metro.Controls
{
public class WindowSettings
public interface IWindowPlacementSettings
{
public static readonly DependencyProperty SaveProperty = DependencyProperty.RegisterAttached("Save", typeof(bool), typeof(WindowSettings), new FrameworkPropertyMetadata(OnSaveInvalidated));
WINDOWPLACEMENT? Placement { get; set; }
void Reload();
void Save();
}

public static void SetSave(DependencyObject dependencyObject, bool enabled)
{
dependencyObject.SetValue(SaveProperty, enabled);
/// <summary>
/// this settings class is the default way to save the placement of the window
/// </summary>
internal class WindowApplicationSettings : ApplicationSettingsBase, IWindowPlacementSettings
{
public WindowApplicationSettings(Window window)
: base(window.GetType().FullName) {
}

internal class WindowApplicationSettings : ApplicationSettingsBase
{
public WindowApplicationSettings(WindowSettings windowSettings)
: base(windowSettings._window.GetType().FullName)
{
}

[UserScopedSetting]
public WINDOWPLACEMENT? Placement
{
get
{
if (this["Placement"] != null)
{
return ((WINDOWPLACEMENT)this["Placement"]);
}
return null;
}
set
{
this["Placement"] = value;
[UserScopedSetting]
public WINDOWPLACEMENT? Placement {
get {
if (this["Placement"] != null) {
return ((WINDOWPLACEMENT)this["Placement"]);
}
return null;
}
set {
this["Placement"] = value;
}
}
private Window _window;
}

public class WindowSettings
{
public static readonly DependencyProperty WindowPlacementSettingsProperty = DependencyProperty.RegisterAttached("WindowPlacementSettings", typeof(IWindowPlacementSettings), typeof(WindowSettings), new FrameworkPropertyMetadata(OnWindowPlacementSettingsInvalidated));

public WindowSettings(Window window)
public static void SetSave(DependencyObject dependencyObject, IWindowPlacementSettings windowPlacementSettings)
{
_window = window;
dependencyObject.SetValue(WindowPlacementSettingsProperty, windowPlacementSettings);
}

private static void OnSaveInvalidated(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
private static void OnWindowPlacementSettingsInvalidated(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) {
var window = dependencyObject as Window;
if (window == null || !((bool)e.NewValue))
if (window == null || !(e.NewValue is IWindowPlacementSettings))
return;

var settings = new WindowSettings(window);
settings.Attach();
var windowSettings = new WindowSettings(window, (IWindowPlacementSettings)e.NewValue);
windowSettings.Attach();
}

private Window _window;
private IWindowPlacementSettings _settings;

public WindowSettings(Window window, IWindowPlacementSettings windowPlacementSettings)
{
_window = window;
_settings = windowPlacementSettings;
}

protected virtual void LoadWindowState()
{
Settings.Reload();
if (_settings == null) return;
_settings.Reload();

if (Settings.Placement == null)
if (_settings.Placement == null)
return;

try
{
var wp = Settings.Placement.Value;
var wp = _settings.Placement.Value;

wp.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
wp.flags = 0;
Expand All @@ -84,11 +92,12 @@ protected virtual void LoadWindowState()

protected virtual void SaveWindowState()
{
if (_settings == null) return;
WINDOWPLACEMENT wp;
var hwnd = new WindowInteropHelper(_window).Handle;
UnsafeNativeMethods.GetWindowPlacement(hwnd, out wp);
Settings.Placement = wp;
Settings.Save();
_settings.Placement = wp;
_settings.Save();
}

private void Attach()
Expand All @@ -109,19 +118,7 @@ private void WindowClosing(object sender, CancelEventArgs e)
_window.Closing -= WindowClosing;
_window.SourceInitialized -= WindowSourceInitialized;
_window = null;
}

private WindowApplicationSettings _windowApplicationSettings;

internal virtual WindowApplicationSettings CreateWindowApplicationSettingsInstance()
{
return new WindowApplicationSettings(this);
}

[Browsable(false)]
internal WindowApplicationSettings Settings
{
get { return _windowApplicationSettings ?? (_windowApplicationSettings = CreateWindowApplicationSettingsInstance()); }
_settings = null;
}
}
}
35 changes: 35 additions & 0 deletions MetroDemo/CustomWindowPlacementSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using MahApps.Metro.Controls;
using MahApps.Metro.Native;

namespace MetroDemo
{
/// <summary>
/// saves the window placement
/// </summary>
public class CustomWindowPlacementSettings : IWindowPlacementSettings
{
private static CustomWindowPlacementSettings instance;

// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static CustomWindowPlacementSettings() {
}

private CustomWindowPlacementSettings() {
}

public static CustomWindowPlacementSettings Instance {
get { return instance ?? (instance = new CustomWindowPlacementSettings()); }
}

public WINDOWPLACEMENT? Placement { get; set; }

public void Reload() {
// load the placement from your custom settings file or something else
}

public void Save() {
// save the placement to your custom settings file or something else
}
}
}
13 changes: 9 additions & 4 deletions MetroDemo/IconsWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<controls:MetroWindow x:Class="MetroDemo.IconsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="Icons" Height="500" Width="600">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:metroDemo="clr-namespace:MetroDemo"
SaveWindowPosition="True"
WindowPlacementSettings="{x:Static metroDemo:CustomWindowPlacementSettings.Instance}"
Title="Icons"
Height="500"
Width="600">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
Expand Down
1 change: 1 addition & 0 deletions MetroDemo/MetroDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<Compile Include="ChildWindow.xaml.cs">
<DependentUpon>ChildWindow.xaml</DependentUpon>
</Compile>
<Compile Include="CustomWindowPlacementSettings.cs" />
<Compile Include="IconsWindow.xaml.cs">
<DependentUpon>IconsWindow.xaml</DependentUpon>
</Compile>
Expand Down

0 comments on commit 55ef43c

Please sign in to comment.