Zapamiętywanie pozycji oraz rozmiaru okna w WPFie

Po wydaniu kolejnej wersji BlipFace jeden z użytkowników napisał, że przydało by się aby BlipFace zapamiętywał położenie oraz rozmiar okna między uruchomieniami.  Po chwili szukania znalazłem post Erwyna van der Meera na temat Remembering window positions in WPF. Niestety zaprezentowane rozwiązanie zapamiętywało rozmiar oraz położenie jednego okna. Długo nie myśląc zmodyfikowałem rozwiązanie aby spełniało moje wymagania.

Aby z niego skorzystać trzeba dodać dwie rzeczy do projektu:

  • do kodu xaml definicji interesującego nas okna trzeba dodać dwie linijki:
xmlns:s="clr-namespace:SaveWindowsPositionTest"
s:SaveWindowsPosition.Save="True"
  • oraz dodać ustawienie do projektu o nazwie klasy naszego okna jak poniżej:

wpfzapamietywanieokna1

I możemy już się cieszyć zapamiętywaniem położenia i rozmiaru okna Windows1. No dobra ale jak to wszystko działa? Kod klasy, która za wszystko odpowiada:

   1: public class SaveWindowsPosition
   2:     {
   3:         #region Constructor
   4:         private Window window = null;
   5:  
   6:         public SaveWindowsPosition(Window window)
   7:         {
   8:             this.window = window;
   9:         }
  10:  
  11:         #endregion
  12:  
  13:         #region Attached "Save" Property Implementation
  14:         /// <summary>
  15:         /// Register the "Save" attached property and the "OnSaveInvalidated" callback 
  16:         /// </summary>
  17:         public static readonly DependencyProperty SaveProperty
  18:            = DependencyProperty.RegisterAttached("Save", typeof(bool), typeof(SaveWindowsPosition),
  19:                 new FrameworkPropertyMetadata(new PropertyChangedCallback(OnSaveInvalidated)));
  20:  
  21:         public static void SetSave(DependencyObject dependencyObject, bool enabled)
  22:         {
  23:             dependencyObject.SetValue(SaveProperty, enabled);
  24:         }
  25:  
  26:         /// <summary>
  27:         /// Called when Save is changed on an object.
  28:         /// </summary>
  29:         private static void OnSaveInvalidated(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
  30:         {
  31:             Window window = dependencyObject as Window;
  32:             if (window != null)
  33:             {
  34:                 if ((bool)e.NewValue)
  35:                 {
  36:                     SaveWindowsPosition settings = new SaveWindowsPosition(window);
  37:                     settings.Attach();
  38:                 }
  39:             }
  40:         }
  41:  
  42:         #endregion
  43:  
  44:         #region Protected Methods
  45:         /// <summary>
  46:         /// Load the Window Size Location and State from the settings object
  47:         /// </summary>
  48:         protected virtual void LoadWindowState()
  49:         {
  50:             Properties.Settings.Default.Reload();
  51:             Rect rect = Rect.Parse(Properties.Settings.Default[window.GetType().Name].ToString().Replace(';', ','));
  52:  
  53:             if (rect != Rect.Empty)
  54:             {
  55:                 this.window.Left = rect.Left;
  56:                 this.window.Top = rect.Top;
  57:                 this.window.Width = rect.Width;
  58:                 this.window.Height = rect.Height;
  59:             }
  60:         }
  61:  
  62:         /// <summary>
  63:         /// Save the Window Size, Location and State to the settings object
  64:         /// </summary>
  65:         protected virtual void SaveWindowState()
  66:         {
  67:             Properties.Settings.Default[window.GetType().Name] = this.window.RestoreBounds.ToString();
  68:             Properties.Settings.Default.Save();
  69:         }
  70:         #endregion
  71:  
  72:         #region Private Methods
  73:  
  74:         private void Attach()
  75:         {
  76:             if (this.window != null)
  77:             {
  78:                 this.window.Closing += new CancelEventHandler(window_Closing);
  79:                 this.window.Initialized += new EventHandler(window_Initialized);
  80:             }
  81:         }
  82:  
  83:         private void window_Initialized(object sender, EventArgs e)
  84:         {
  85:             LoadWindowState();
  86:         }
  87:  
  88:         private void window_Closing(object sender, CancelEventArgs e)
  89:         {
  90:             SaveWindowState();
  91:         }
  92:         #endregion
  93:     }

A teraz kilka słów o klasie SaveWindowsPosition:

  • w regionie Attached "Save" Property Implementation następuje rejestracja właściwości Save (tą, do której w xamlu okna przekazujemy wartość true) oraz callbacku OnSaveInvalidated, w którym podpinamy się pod zdarzenia Closing oraz Initialized okna, w których zapisujemy oraz ustawiamy położenie oraz rozmiar okna
  • metody LoadWindowState odczytuje ustawiania oraz SaveWindowState je zapisuje w pliku app.config. Założyłem sobie, że ustawiania mają taką samą nazwę jak nazwa klasy okna (window.GetType().Name) ale bardzo łatwo można to zmienić i uwzględniać np. nazwę okna (window.Name).

Demo przestawiające użycie powyższego rozwiązania - SaveWindowsPositionTest.zip (54,51 kb)

Tagi: , , ,

Pingbacks and trackbacks (1)+

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Eastgroup.pl na facebooku