2010-05-17 2 views
3

Что было бы лучшим способом сохранить положение и размер окна в приложении WPF?Сохранение WPF WIndow и Position

В настоящее время я сохраняю размер окна и положение приложения WPF. Вот событие я ручка:

  1. SourceInitialized: Сохраненная информация загружается на окно
  2. WindowClosing: Текущая информация сохраняется в резервном хранилище

(я скопировал это из пример).

Проблема заключается в том, что при минимизации и восстановлении окна восстанавливаются настройки из последнего окна.

Теперь, пожар события StateChanged ПОСЛЕ того, как окно сведено к минимуму, так что это не похоже на то, что мне нужно.

Благодаря

ответ

9

ли себя и своих пользователей пользу и использовать LocationChanged событие и SizeChanged событие, чтобы сохранить настройки в то время. Нет ничего более раздражающего, чем приложение, которое получает амнезию, если процесс выходит аномально, и настройки не сохраняются (cough ... explorer ... cough ...)

Затем просто проверьте, чтобы WindowState == Обычный, прежде чем сохранять настройки. Очевидно, что его бессмысленно сохранять положение свернутого или максимизированного окна.

Что касается того, когда загружать настройки, хорошо, что вы можете просто сделать в конструкторе после вызова InitializeComponent, или вы можете использовать событие Initialized. Нет реальной причины использовать событие SourceInitialized, если вы не делаете что-то с HWND напрямую, что не должно быть необходимым.

+0

Важное значение имеет положение максимизированного окна: на каком мониторе он максимизировался? –

+0

Отличный пункт. Но, вероятно, лучше сохранить идентификатор монитора и максимизированное состояние, а не максимизировать границы, так или иначе, если разрешение изменится. – Josh

0

Вы делаете это посредством привязки данных? Так я делаю свой размер и положение окна. Обычно у меня есть файл UserConfig.xml, который сохраняется в профиле пользователей. Затем я создаю элементы там, где я их привязываю в программе. У меня есть словарь ресурсов Application.xaml, относящийся к этому файлу, и все настройки, которые я хочу установить для XPaths в XML. Затем я просто сохраняю документ xml в памяти при выходе. Только одно событие для обработки, беспорядок, без суеты.

И вы можете расширить его, чтобы охватить столько настроек, сколько вам нравится в отношении пользовательского интерфейса. Добавление настроек сантехники немного сложнее, но не так страшно.

1

Используйте объект WindowInteropHelper, чтобы получить дескриптор окна и использовать метод Screen.FromHandle для получения фактического экрана, в котором находится окно. При сохранении обязательно сохраните границы экрана на всякий случай, если он больше не существует.

Одно из предостережений при восстановлении экрана до его прежнего состояния - это необходимо сделать после создания дескриптора окна, поэтому он не может это сделать в конструкторе, иначе он не будет работать должным образом в ситуациях с несколькими мониторами. Попробуйте сделать это на SourceInitialized обратном вызове

0

У меня есть решение для сохранения размера и состояния, вы можете продлить его, чтобы сохранить позицию. Это делается с помощью Поведения. Просто привязка ширины и высоты не работала должным образом, поскольку она перезаписывала размер «нормального» состояния с максимальными размерами. Вот почему есть некоторые дополнительные проверки, такие как if(state == normal)

Существует Config Недвижимость на моем окне DataContext. Для этого вам понадобится ссылка на System.Windows.Interactivity.

public class MainWindowSaveStateBehavior : Behavior<Window> 
{ 
    public Config Config 
    { 
     get { return (Config)GetValue(ConfigProperty); } 
     set { SetValue(ConfigProperty, value); } 
    } 

    public static readonly DependencyProperty ConfigProperty = 
     DependencyProperty.Register("Config", typeof(Config), typeof(MainWindowSaveStateBehavior), new PropertyMetadata(Config_Changed)); 

    private static void Config_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var b = d as MainWindowSaveStateBehavior; 
     if(e.NewValue != null) b.LoadSettings(); 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.SizeChanged += Window_SizeChanged; 
     AssociatedObject.StateChanged += Window_StateChanged; 
     LoadSettings(); 
    } 

    bool _initialized = false; 

    private void Window_StateChanged(object sender, EventArgs e) 
    { 
     SaveSettings(); 
    } 

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     SaveSettings(); 
    } 

    private void LoadSettings() 
    { 
     if (Config == null) return; 

     AssociatedObject.Width = Config.WindowWidth; 
     AssociatedObject.Height = Config.WindowHeight; 
     AssociatedObject.WindowState = Config.WindowState; 

     _initialized = true; 
    } 

    private void SaveSettings() 
    { 
     if (Config == null || !_initialized) return; 

     Config.WindowState = AssociatedObject.WindowState; 
     if(AssociatedObject.WindowState == WindowState.Normal) 
     { 
      Config.WindowWidth = AssociatedObject.Width; 
      Config.WindowHeight = AssociatedObject.Height; 
     } 
    } 
} 

В Xaml использовать поведение путем добавления пространств имен

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:b="<the namespace your behavior lives in>" 

И затем присоедините поведение

<i:Interaction.Behaviors> 
    <b:MainWindowSaveStateBehavior Config="{Binding Config}" /> 
</i:Interaction.Behaviors> 

Затем вы просто должны загрузить и сохранить конфиг в вашем DataContext при запуске /неисправность.