it-swarm.com.de

.NET WPF Ermittle die Fenstergröße zwischen den Sitzungen

Wenn der Benutzer das Fenster meiner Anwendung ändert, möchte ich, dass die Anwendung die gleiche Größe hat, wenn die Anwendung erneut geöffnet wird.

Zuerst halte ich zwar das SizeChanged-Ereignis und speichere Höhe und Breite, aber ich denke, es muss eine einfachere Lösung geben.

Ziemlich einfaches Problem, aber ich kann keine einfache Lösung dafür finden.

84
Daniil Harik

Speichern Sie die Werte in der Datei user.config.

Sie müssen den Wert in der Einstellungsdatei erstellen - er sollte sich im Eigenschaftenordner befinden. Erstellen Sie fünf Werte:

  • Top vom Typ double
  • Left vom Typ double
  • Height vom Typ double
  • Width vom Typ double
  • Maximized vom Typ bool - hält fest, ob das Fenster maximiert ist oder nicht. Wenn Sie weitere Informationen speichern möchten, ist ein anderer Typ oder eine andere Struktur erforderlich.

Initialisieren Sie die ersten beiden auf 0 und die zweiten zwei auf die Standardgröße Ihrer Anwendung und die letzte auf falsch.

Im Konstruktor:

this.Top = Properties.Settings.Default.Top;
this.Left = Properties.Settings.Default.Left;
this.Height = Properties.Settings.Default.Height;
this.Width = Properties.Settings.Default.Width;
// Very quick and dirty - but it does the job
if (Properties.Settings.Default.Maximized)
{
    WindowState = WindowState.Maximized;
}

Erstellen Sie einen Window_Closing-Ereignishandler, und fügen Sie Folgendes hinzu:

if (WindowState == WindowState.Maximized)
{
    // Use the RestoreBounds as the current values will be 0, 0 and the size of the screen
    Properties.Settings.Default.Top = RestoreBounds.Top;
    Properties.Settings.Default.Left = RestoreBounds.Left;
    Properties.Settings.Default.Height = RestoreBounds.Height;
    Properties.Settings.Default.Width = RestoreBounds.Width;
    Properties.Settings.Default.Maximized = true;
}
else
{
    Properties.Settings.Default.Top = this.Top;
    Properties.Settings.Default.Left = this.Left;
    Properties.Settings.Default.Height = this.Height;
    Properties.Settings.Default.Width = this.Width;
    Properties.Settings.Default.Maximized = false;
}

Properties.Settings.Default.Save();

Dies schlägt fehl, wenn der Benutzer den Anzeigebereich verkleinert - entweder durch Trennen eines Bildschirms oder Ändern der Bildschirmauflösung -, während die Anwendung geschlossen wird. Sie sollten daher vor dem Übernehmen der Werte prüfen, ob der gewünschte Speicherort und die gewünschte Größe noch gültig sind.

109
ChrisF

Eigentlich brauchen Sie dafür keinen Code-Behind (außer zum Speichern der Einstellungen). Sie können eine benutzerdefinierte Markup-Erweiterung verwenden, um die Fenstergröße und -position wie folgt an die Einstellungen zu binden:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="Window1"
        Height="{my:SettingBinding Height}"
        Width="{my:SettingBinding Width}"
        Left="{my:SettingBinding Left}"
        Top="{my:SettingBinding Top}">

Den Code für diese Markup-Erweiterung finden Sie hier: http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

68
Thomas Levesque

Ich habe gerade einen Blogeintrag geschrieben, in dem beschrieben wird, wie dies auf einfache und robuste Weise geschieht. Es verwendet die von Andy erwähnten GetWindowPlacement- und SetWindowPlacement-Funktionen, wobei jedoch einige der seltsamen Verhaltensweisen, die er erwähnt hat, aufgeräumt wurden:

https://engy.us/blog/2010/03/08/saving-window-size-and-location-in-wpf-and-winforms/

Hier sind einige Unterschiede zu anderen Antworten:

  • Dieser Code ist sich der Änderungen des Monitors bewusst, daher kann er ein Fenster verschieben, wenn ein Monitor getrennt wird (also nicht vom Bildschirm getrennt). 
  • Es kann auch die normale Größe des Fensters speichern, selbst wenn es maximiert ist, sodass es weiß, was wiederhergestellt werden soll, wenn es nicht maximiert ist. 
  • Es konsolidiert auch den Fensterstatus in einer einzelnen Zeichenfolge, die einfacher zu bestehen ist.
  • Code definiert eine Klasse, die für ein oder mehrere Fenster in Ihrem Projekt verwendet werden kann, indem Sie einfach zwei Ereignisse einbinden. Somit stört es keine Ihrer Projektdateien.
39
RandomEngy

Sie können zwar selbst "rollen" und die Einstellungen manuell speichern, und im Allgemeinen wird es funktionieren, aber es ist sehr einfach, nicht alle Fälle korrekt zu behandeln. Es ist viel besser, das Betriebssystem die Arbeit für Sie erledigen zu lassen, indem Sie GetWindowPlacement () at exit und SetWindowPlacement () beim Start aufrufen. Es behandelt alle verrückten Edge-Fälle, die auftreten können (mehrere Monitore speichern die normale Größe des Fensters, wenn es geschlossen ist, während es maximiert ist usw.), so dass Sie dies nicht müssen.

Dieses MSDN-Beispiel zeigt, wie Sie diese mit einer WPF-App verwenden. Das Beispiel ist nicht perfekt (das Fenster beginnt beim ersten Durchlauf in der oberen linken Ecke so klein wie möglich, und der Settings-Designer spart einen Wert vom Typ WINDOWPLACEMENT), aber es sollte Ihnen zumindest den Anfang erleichtern .

33
Andy

Die "Langform" -Bindung, die Thomas oben veröffentlicht hat, erfordert fast keine Codierung. Stellen Sie nur sicher, dass Sie über die Namensraumbindung verfügen:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:p="clr-namespace:WpfApplication1.Properties"
        Title="Window1"
        Height="{Binding Source={x:Static p:Settings.Default}, Path=Height, Mode=TwoWay}"
        Width="{Binding Source={x:Static p:Settings.Default}, Path=Width, Mode=TwoWay}"
        Left="{Binding Source={x:Static p:Settings.Default}, Path=Left, Mode=TwoWay}"
        Top="{Binding Source={x:Static p:Settings.Default}, Path=Top, Mode=TwoWay}">

Dann um den Code-Behind zu sparen:

private void frmMain_Closed(object sender, EventArgs e)
{
    Properties.Settings.Default.Save();
}
27
Lance Cleveland

Alternativ können Sie auch die folgende Vorgehensweise wählen ( siehe Quelle ). Fügen Sie die WindowSettings-Klasse Ihrem Projekt hinzu und fügen Sie WindowSettings.Save="True" in die Kopfzeile Ihres Hauptfensters ein:

<Window x:Class="YOURPROJECT.Views.ShellView"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    xmlns:Services="clr-namespace:YOURNAMESPACE.Services" 
    Services:WindowSettings.Save="True">

Wobei WindowSettings wie folgt definiert ist:

using System;
using System.ComponentModel;
using System.Configuration;
using System.Windows;

namespace YOURNAMESPACE.Services
{
/// <summary>
///   Persists a Window's Size, Location and WindowState to UserScopeSettings
/// </summary>
public class WindowSettings
{
    #region Fields

    /// <summary>
    ///   Register the "Save" attached property and the "OnSaveInvalidated" callback
    /// </summary>
    public static readonly DependencyProperty SaveProperty = DependencyProperty.RegisterAttached("Save", typeof (bool), typeof (WindowSettings), new FrameworkPropertyMetadata(OnSaveInvalidated));

    private readonly Window mWindow;

    private WindowApplicationSettings mWindowApplicationSettings;

    #endregion Fields

    #region Constructors

    public WindowSettings(Window pWindow) { mWindow = pWindow; }

    #endregion Constructors

    #region Properties

    [Browsable(false)] public WindowApplicationSettings Settings {
        get {
            if (mWindowApplicationSettings == null) mWindowApplicationSettings = CreateWindowApplicationSettingsInstance();
            return mWindowApplicationSettings;
        }
    }

    #endregion Properties

    #region Methods

    public static void SetSave(DependencyObject pDependencyObject, bool pEnabled) { pDependencyObject.SetValue(SaveProperty, pEnabled); }

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

    /// <summary>
    ///   Load the Window Size Location and State from the settings object
    /// </summary>
    protected virtual void LoadWindowState() {
        Settings.Reload();
        if (Settings.Location != Rect.Empty) {
            mWindow.Left = Settings.Location.Left;
            mWindow.Top = Settings.Location.Top;
            mWindow.Width = Settings.Location.Width;
            mWindow.Height = Settings.Location.Height;
        }
        if (Settings.WindowState != WindowState.Maximized) mWindow.WindowState = Settings.WindowState;
    }

    /// <summary>
    ///   Save the Window Size, Location and State to the settings object
    /// </summary>
    protected virtual void SaveWindowState() {
        Settings.WindowState = mWindow.WindowState;
        Settings.Location = mWindow.RestoreBounds;
        Settings.Save();
    }

    /// <summary>
    ///   Called when Save is changed on an object.
    /// </summary>
    private static void OnSaveInvalidated(DependencyObject pDependencyObject, DependencyPropertyChangedEventArgs pDependencyPropertyChangedEventArgs) {
        var window = pDependencyObject as Window;
        if (window != null)
            if ((bool) pDependencyPropertyChangedEventArgs.NewValue) {
                var settings = new WindowSettings(window);
                settings.Attach();
            }
    }

    private void Attach() {
        if (mWindow != null) {
            mWindow.Closing += WindowClosing;
            mWindow.Initialized += WindowInitialized;
            mWindow.Loaded += WindowLoaded;
        }
    }

    private void WindowClosing(object pSender, CancelEventArgs pCancelEventArgs) { SaveWindowState(); }

    private void WindowInitialized(object pSender, EventArgs pEventArgs) { LoadWindowState(); }

    private void WindowLoaded(object pSender, RoutedEventArgs pRoutedEventArgs) { if (Settings.WindowState == WindowState.Maximized) mWindow.WindowState = Settings.WindowState; }

    #endregion Methods

    #region Nested Types

    public class WindowApplicationSettings : ApplicationSettingsBase
    {
        #region Constructors

        public WindowApplicationSettings(WindowSettings pWindowSettings) { }

        #endregion Constructors

        #region Properties

        [UserScopedSetting] public Rect Location {
            get {
                if (this["Location"] != null) return ((Rect) this["Location"]);
                return Rect.Empty;
            }
            set { this["Location"] = value; }
        }

        [UserScopedSetting] public WindowState WindowState {
            get {
                if (this["WindowState"] != null) return (WindowState) this["WindowState"];
                return WindowState.Normal;
            }
            set { this["WindowState"] = value; }
        }

        #endregion Properties
    }

    #endregion Nested Types
}
}
4
Erik Vullings

Dies ist die eleganteste Lösung, die ich über das Internet gesehen habe. Überprüfen Sie dies heraus:

http://blogs.msdn.com/b/davidrickard/archive/2010/03/09/saving-window-size-and-location-in-wpf-and-winforms.aspx

Es funktioniert auch für WPF und für WinForms.

3
Alexandru Dicu

Die Standardmethode ist die Verwendung von Einstellungsdateien. Das Problem mit Einstellungsdateien besteht darin, dass Sie alle Einstellungen definieren und den Code schreiben müssen, der die Daten selbst hin und her kopiert. Ziemlich langweilig, wenn Sie viele Eigenschaften haben, um die Übersicht zu behalten.

Ich habe dazu eine recht flexible und sehr einfach zu verwendende Bibliothek erstellt. Sie sagen nur, welche Eigenschaften von welchem ​​Objekt verfolgt werden sollen, und der Rest erledigt das alles. Sie können den Mist auch nach Belieben konfigurieren.

Die Bibliothek heißt Jot (github), hier ist ein alter CodeProject-Artikel Ich habe darüber geschrieben.

So können Sie die Größe und Position eines Fensters nachverfolgen:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

Jot vs. Einstellungsdateien: Mit Jot gibt es wesentlich weniger Code und es ist weniger fehleranfällig, da Sie nur jede Eigenschaft einmal erwähnen müssen. Bei Einstellungsdateien müssen Sie jede Eigenschaft 5-mal: einmal angeben, wenn Sie die Eigenschaft explizit erstellen, und vier weitere Male im Code, der die Werte hin und her kopiert.

Speicherung, Serialisierung usw. sind vollständig konfigurierbar. Wenn Sie IOC verwenden, können Sie es sogar so anschließen, dass die Nachverfolgung automatisch auf alle Objekte angewendet wird, die aufgelöst werden, sodass Sie nur ein Attribut [Verfolgbar] darauf setzen müssen, damit eine Eigenschaft dauerhaft bleibt.

Ich schreibe das alles, weil ich denke, dass die Bibliothek erstklassig ist und ich darüber reden möchte.

3
anakic

Ich habe eine kurze Klasse geschrieben, die dies tut. So heißt es:

    public MainWindow()
    {
        FormSizeSaver.RegisterForm(this, () => Settings.Default.MainWindowSettings,
                                   s =>
                                   {
                                       Settings.Default.MainWindowSettings = s;
                                       Settings.Default.Save();
                                   });
        InitializeComponent();
        ...

Und hier ist der Code:

public class FormSizeSaver
{
    private readonly Window window;
    private readonly Func<FormSizeSaverSettings> getSetting;
    private readonly Action<FormSizeSaverSettings> saveSetting;
    private FormSizeSaver(Window window, Func<string> getSetting, Action<string> saveSetting)
    {
        this.window = window;
        this.getSetting = () => FormSizeSaverSettings.FromString(getSetting());
        this.saveSetting = s => saveSetting(s.ToString());

        window.Initialized += InitializedHandler;
        window.StateChanged += StateChangedHandler;
        window.SizeChanged += SizeChangedHandler;
        window.LocationChanged += LocationChangedHandler;
    }

    public static FormSizeSaver RegisterForm(Window window, Func<string> getSetting, Action<string> saveSetting)
    {
        return new FormSizeSaver(window, getSetting, saveSetting);
    }


    private void SizeChangedHandler(object sender, SizeChangedEventArgs e)
    {
        var s = getSetting();
        s.Height = e.NewSize.Height;
        s.Width = e.NewSize.Width;
        saveSetting(s);
    }

    private void StateChangedHandler(object sender, EventArgs e)
    {
        var s = getSetting();
        if (window.WindowState == WindowState.Maximized)
        {
            if (!s.Maximized)
            {
                s.Maximized = true;
                saveSetting(s);
            }
        }
        else if (window.WindowState == WindowState.Normal)
        {
            if (s.Maximized)
            {
                s.Maximized = false;
                saveSetting(s);
            }
        }
    }

    private void InitializedHandler(object sender, EventArgs e)
    {
        var s = getSetting();
        window.WindowState = s.Maximized ? WindowState.Maximized : WindowState.Normal;

        if (s.Height != 0 && s.Width != 0)
        {
            window.Height = s.Height;
            window.Width = s.Width;
            window.WindowStartupLocation = WindowStartupLocation.Manual;
            window.Left = s.XLoc;
            window.Top = s.YLoc;
        }
    }

    private void LocationChangedHandler(object sender, EventArgs e)
    {
        var s = getSetting();
        s.XLoc = window.Left;
        s.YLoc = window.Top;
        saveSetting(s);
    }
}

[Serializable]
internal class FormSizeSaverSettings
{
    public double Height, Width, YLoc, XLoc;
    public bool Maximized;

    public override string ToString()
    {
        using (var ms = new MemoryStream())
        {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, this);
            ms.Position = 0;
            byte[] buffer = new byte[(int)ms.Length];
            ms.Read(buffer, 0, buffer.Length);
            return Convert.ToBase64String(buffer);
        }
    }

    internal static FormSizeSaverSettings FromString(string value)
    {
        try
        {
            using (var ms = new MemoryStream(Convert.FromBase64String(value)))
            {
                var bf = new BinaryFormatter();
                return (FormSizeSaverSettings) bf.Deserialize(ms);
            }
        }
        catch (Exception)
        {
            return new FormSizeSaverSettings();
        }
    }
}
1
tster

Es gibt ein NuGet Project RestoreWindowPlace Siehe auf github das erledigt das alles für Sie und speichert die Informationen in einer XML-Datei.

Damit es an einem Fenster funktioniert, ist es so einfach wie das Aufrufen von:

((App)Application.Current).WindowPlace.Register(this, "MainWindow");

In App erstellen Sie die Klasse, die Ihre Fenster verwaltet. Für weitere Informationen siehe den Github-Link oben.

0
Chuck Savage

Ich habe eine generischere Lösung entwickelt, die auf der brillanten Antwort von RandomEngys basiert. Es speichert die Position in der Datei im laufenden Ordner und Sie müssen keine neuen Eigenschaften für jedes neue Fenster erstellen, das Sie erstellen. Diese Lösung funktioniert gut für mich mit minimalem Code im Code.

using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Interop;
using System.Xml;
using System.Xml.Serialization;

namespace WindowPlacementNameSpace
{

    // RECT structure required by WINDOWPLACEMENT structure
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public RECT(int left, int top, int right, int bottom)
        {
            this.Left = left;
            this.Top = top;
            this.Right = right;
            this.Bottom = bottom;
        }
    }

    // POINT structure required by WINDOWPLACEMENT structure
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;

        public POINT(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
    }

    // WINDOWPLACEMENT stores the position, size, and state of a window
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWPLACEMENT
    {
        public int length;
        public int flags;
        public int showCmd;
        public POINT minPosition;
        public POINT maxPosition;
        public RECT normalPosition;
    }

    public static class WindowPlacement
    {
        private static readonly Encoding Encoding = new UTF8Encoding();
        private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(WINDOWPLACEMENT));

        [DllImport("user32.dll")]
        private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        private static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);

        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;

        private static void SetPlacement(IntPtr windowHandle, string placementXml)
        {
            if (string.IsNullOrEmpty(placementXml))
            {
                return;
            }

            byte[] xmlBytes = Encoding.GetBytes(placementXml);

            try
            {
                WINDOWPLACEMENT placement;
                using (MemoryStream memoryStream = new MemoryStream(xmlBytes))
                {
                    placement = (WINDOWPLACEMENT)Serializer.Deserialize(memoryStream);
                }

                placement.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
                placement.flags = 0;
                placement.showCmd = (placement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : placement.showCmd);
                SetWindowPlacement(windowHandle, ref placement);
            }
            catch (InvalidOperationException)
            {
                // Parsing placement XML failed. Fail silently.
            }
        }

        private static string GetPlacement(IntPtr windowHandle)
        {
            WINDOWPLACEMENT placement;
            GetWindowPlacement(windowHandle, out placement);

            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8))
                {
                    Serializer.Serialize(xmlTextWriter, placement);
                    byte[] xmlBytes = memoryStream.ToArray();
                    return Encoding.GetString(xmlBytes);
                }
            }
        }
        public static void ApplyPlacement(this Window window)
        {
            var className = window.GetType().Name;
            try
            {
                var pos = File.ReadAllText(Directory + "\\" + className + ".pos");
                SetPlacement(new WindowInteropHelper(window).Handle, pos);
            }
            catch (Exception exception)
            {
                Log.Error("Couldn't read position for " + className, exception);
            }

        }

        public static void SavePlacement(this Window window)
        {
            var className = window.GetType().Name;
            var pos =  GetPlacement(new WindowInteropHelper(window).Handle);
            try
            {
                File.WriteAllText(Directory + "\\" + className + ".pos", pos);
            }
            catch (Exception exception)
            {
                Log.Error("Couldn't write position for " + className, exception);
            }
        }
        private static string Directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

    }
}

Fügen Sie in Ihrem Code hinter diesen beiden Methoden hinzu

///This method is save the actual position of the window to file "WindowName.pos"
private void ClosingTrigger(object sender, EventArgs e)
{
    this.SavePlacement();
}
///This method is load the actual position of the window from the file
protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    this.ApplyPlacement();
}

im xaml-Fenster fügen Sie dies hinzu

Closing="ClosingTrigger"
0
Bjorn

Ich verwende die Antwort von Lance Cleveland und binde das Setting. Aber ich benutze etwas mehr Code, um zu vermeiden, dass mein Fenster außerhalb des Bildschirms ist.

private void SetWindowSettingsIntoScreenArea()
{
    // first detect Screen, where we will display the Window
    // second correct bottom and right position
    // then the top and left position.
    // If Size is bigger than current Screen, it's still possible to move and size the Window

    // get the screen to display the window
    var screen = System.Windows.Forms.Screen.FromPoint(new System.Drawing.Point((int)Default.Left, (int)Default.Top));

    // is bottom position out of screen for more than 1/3 Height of Window?
    if (Default.Top + (Default.Height / 3) > screen.WorkingArea.Height)
        Default.Top = screen.WorkingArea.Height - Default.Height;

    // is right position out of screen for more than 1/2 Width of Window?
    if (Default.Left + (Default.Width / 2) > screen.WorkingArea.Width)
        Default.Left = screen.WorkingArea.Width - Default.Width;

    // is top position out of screen?
    if (Default.Top < screen.WorkingArea.Top)
        Default.Top = screen.WorkingArea.Top;

    // is left position out of screen?
    if (Default.Left < screen.WorkingArea.Left)
        Default.Left = screen.WorkingArea.Left;
}
0
Markus

Erstellen Sie in Ihren Standardeinstellungen eine Zeichenfolge mit dem Namen WindowXml.

Verwenden Sie diese Erweiterungsmethode für die Ereignisse "Fenster geladen und schließen", um die Fenstergröße und den Speicherort wiederherzustellen und zu speichern.

using YourProject.Properties;
using System;
using System.Linq;
using System.Windows;
using System.Xml.Linq;

namespace YourProject.Extensions
{
    public static class WindowExtensions
    {
        public static void SaveSizeAndLocation(this Window w)
        {
            try
            {
                var s = "<W>";
                s += GetNode("Top", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Top : w.Top);
                s += GetNode("Left", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Left : w.Left);
                s += GetNode("Height", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Height : w.Height);
                s += GetNode("Width", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Width : w.Width);
                s += GetNode("WindowState", w.WindowState);
                s += "</W>";

                Settings.Default.WindowXml = s;
                Settings.Default.Save();
            }
            catch (Exception)
            {
            }
        }

        public static void RestoreSizeAndLocation(this Window w)
        {
            try
            {
                var xd = XDocument.Parse(Settings.Default.WindowXml);
                w.WindowState = (WindowState)Enum.Parse(typeof(WindowState), xd.Descendants("WindowState").FirstOrDefault().Value);
                w.Top = Convert.ToDouble(xd.Descendants("Top").FirstOrDefault().Value);
                w.Left = Convert.ToDouble(xd.Descendants("Left").FirstOrDefault().Value);
                w.Height = Convert.ToDouble(xd.Descendants("Height").FirstOrDefault().Value);
                w.Width = Convert.ToDouble(xd.Descendants("Width").FirstOrDefault().Value);
            }
            catch (Exception)
            {
            }
        }

        private static string GetNode(string name, object value)
        {
            return string.Format("<{0}>{1}</{0}>", name, value);
        }
    }
}
0
Tempeck

Das könnte dir gefallen:

public class WindowStateHelper
{
    public static string ToXml(System.Windows.Window win)
    {
        XElement bounds = new XElement("Bounds");
        if (win.WindowState == System.Windows.WindowState.Maximized)
        {
            bounds.Add(new XElement("Top", win.RestoreBounds.Top));
            bounds.Add(new XElement("Left", win.RestoreBounds.Left));
            bounds.Add(new XElement("Height", win.RestoreBounds.Height));
            bounds.Add(new XElement("Width", win.RestoreBounds.Width));
        }
        else
        {
            bounds.Add(new XElement("Top", win.Top));
            bounds.Add(new XElement("Left", win.Left));
            bounds.Add(new XElement("Height", win.Height));
            bounds.Add(new XElement("Width", win.Width));
        }
        XElement root = new XElement("WindowState",
            new XElement("State", win.WindowState.ToString()),
            new XElement("Visibility", win.Visibility.ToString()),
            bounds);

        return root.ToString();
    }

    public static void FromXml(string xml, System.Windows.Window win)
    {
        try
        {
            XElement root = XElement.Parse(xml);
            string state = root.Descendants("State").FirstOrDefault().Value;
            win.WindowState = (System.Windows.WindowState)Enum.Parse(typeof(System.Windows.WindowState), state);

            state = root.Descendants("Visibility").FirstOrDefault().Value;
            win.Visibility = (System.Windows.Visibility)Enum.Parse(typeof(System.Windows.Visibility), state);

            XElement bounds = root.Descendants("Bounds").FirstOrDefault();
            win.Top = Convert.ToDouble(bounds.Element("Top").Value);
            win.Left = Convert.ToDouble(bounds.Element("Left").Value);
            win.Height = Convert.ToDouble(bounds.Element("Height").Value);
            win.Width = Convert.ToDouble(bounds.Element("Width").Value);
        }
        catch (Exception x)
        {
            System.Console.WriteLine(x.ToString());
        }
    }
}

Wenn die App geschlossen wird:

        Properties.Settings.Default.Win1Placement = WindowStateHelper.ToXml(win1);
        Properties.Settings.Default.Win2Placement = WindowStateHelper.ToXml(win2);
        ...

Wenn die App startet:

        WindowStateHelper.FromXml(Properties.Settings.Default.Win1Placement, win1);
        WindowStateHelper.FromXml(Properties.Settings.Default.Win2Placement, win2);
        ...
0
paul