andrew4582

WindowStateManager WPF

Jul 22nd, 2012
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.76 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Text;
  5. using System.Xml;
  6. using System.Xml.Serialization;
  7.  
  8. namespace System.Windows {
  9.     /// <summary>
  10.     /// Remembers the window's size and position by saving window state to a xml file
  11.     ///<example>
  12.     ///
  13.     /*
  14.      WindowStateManager _windowState;
  15.  
  16.         public MainWindow() {
  17.             InitializeComponent();
  18.  
  19.             _windowState = new WindowStateManager(this);
  20.         }
  21.      */
  22.     ///
  23.     ///</example>
  24.     /// </summary>
  25.     public class WindowStateManager {
  26.  
  27.         const string DATA_FILE_NAME = "WindowStateManager.xml";
  28.         const string DATA_FILE_FORMAT = "WindowStateManager_{0}.xml";
  29.  
  30.         Window _parentWindow;
  31.         WindowStateData _data;
  32.         WindowStateData _originalData;
  33.         double _lastWidth;
  34.         double _lastHeight;
  35.         double _lastTop;
  36.         double _lastLeft;
  37.  
  38.         public IDictionary<string,object> AdditionalData {
  39.             get {
  40.                 return Data.AdditionalData;
  41.             }
  42.         }
  43.  
  44.         public WindowStateData Data {
  45.             get {
  46.                 return _data;
  47.             }
  48.         }
  49.  
  50.         public Window ParentWindow {
  51.             get {
  52.                 return _parentWindow;
  53.             }
  54.         }
  55.  
  56.         public WindowStateManager(Window parentWindow) {
  57.             bool createdNewInstance = false;
  58.  
  59.             _parentWindow = parentWindow;
  60.             _data = LoadData(out createdNewInstance);
  61.             _originalData = _data.Copy();
  62.            
  63.             if(createdNewInstance)
  64.                 _parentWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  65.             else
  66.                 _parentWindow.WindowStartupLocation = WindowStartupLocation.Manual;
  67.  
  68.             _parentWindow.StateChanged += ParentWindow_StateChanged;
  69.             _parentWindow.LocationChanged += ParentWindow_LocationChanged;
  70.             _parentWindow.SizeChanged += ParentWindow_SizeChanged;
  71.             _parentWindow.Closing += ParentWindow_Closing;
  72.            
  73.             Data.UpdateWindowProperties(ParentWindow);
  74.             Debug.WriteLine("WindowStateManager ctr: " + Data.ToString());
  75.         }
  76.    
  77.  
  78.         public T GetAdditionalData<T>(string key,T defaultValue = default(T)) {
  79.             if(!AdditionalData.ContainsKey(key))
  80.                 return defaultValue;
  81.             object data = AdditionalData[key];
  82.             if(data == null)
  83.                 return defaultValue;
  84.             return (T)data;
  85.         }
  86.  
  87.         void ParentWindow_StateChanged(object sender,EventArgs e)
  88.         {
  89.             _lastTop = ParentWindow.Top;
  90.             _lastLeft = ParentWindow.Left;
  91.             _lastWidth = ParentWindow.Width;
  92.             _lastHeight = ParentWindow.Height;
  93.         }
  94.  
  95.         void ParentWindow_LocationChanged(object sender,EventArgs e)
  96.         {
  97.             _lastTop = ParentWindow.Top;
  98.             _lastLeft = ParentWindow.Left;
  99.             _lastWidth = ParentWindow.Width;
  100.             _lastHeight = ParentWindow.Height;
  101.         }
  102.         void ParentWindow_SizeChanged(object sender,SizeChangedEventArgs e)
  103.         {
  104.             if(ParentWindow.WindowState == WindowState.Normal)
  105.             {
  106.                 if(e.WidthChanged)
  107.                     _lastWidth = e.NewSize.Width;
  108.                 if(e.HeightChanged)
  109.                     _lastHeight = e.NewSize.Height;
  110.             }
  111.         }
  112.  
  113.         void ParentWindow_Closing(object sender,System.ComponentModel.CancelEventArgs e) {
  114.  
  115.             Data.SetWindowProperties(ParentWindow,
  116.                 new Size(_lastWidth,_lastHeight),
  117.                 new Point(_lastTop,_lastLeft),
  118.                 _originalData);
  119.             SaveData(Data);
  120.             Debug.WriteLine("ParentWindow_Closing: " + Data.ToString());
  121.         }
  122.         string GetDataFileName() {
  123.             if(_parentWindow == null)
  124.                 return DATA_FILE_NAME;
  125.  
  126.             return string.Format(DATA_FILE_FORMAT,_parentWindow.GetType().Name);
  127.         }
  128.  
  129.         WindowStateData LoadData(out bool createdNewInstance) {
  130.             string fn = GetDataFileName();
  131.             try
  132.             {
  133.                 if(File.Exists(fn))
  134.                 {
  135.                     createdNewInstance = false;
  136.                     return XmlHelpers.ReadObjectFromFile<WindowStateData>(fn);
  137.                 }
  138.                 else
  139.                 {
  140.                     createdNewInstance = true;
  141.                     return new WindowStateData();
  142.                 }
  143.             }
  144.             catch
  145.             {
  146.                 createdNewInstance = true;
  147.                 return new WindowStateData();
  148.             }
  149.         }
  150.  
  151.         void SaveData(WindowStateData data) {
  152.             string fn = GetDataFileName();
  153.             XmlHelpers.SaveObjectToFile(data,fn);
  154.         }
  155.  
  156.         [Serializable]
  157.         public class WindowStateData {
  158.  
  159.             SerializableDictionary<string,object> _additionalData;
  160.  
  161.             public void UpdateWindowProperties(Window w) {
  162.  
  163.                 WindowStateData data = this;
  164.  
  165.                 w.Width = data.Width;
  166.                 w.Height = data.Height;
  167.  
  168.                 if(data.Top > -1)
  169.                     w.Top = data.Top;
  170.                 if(data.Left > -1)
  171.                     w.Left = data.Left;
  172.  
  173.                 if(data.AllowMaximized && data.State == WindowState.Maximized) {
  174.                     w.WindowState = WindowState.Maximized;
  175.                     return;
  176.                 }
  177.             }
  178.  
  179.             public void SetWindowLocation(Window w) {
  180.                 WindowStateData data = this;
  181.                 data.State = w.WindowState;
  182.                 data.Top = w.Top;
  183.                 data.Left = w.Left;
  184.             }
  185.             public void SetWindowProperties(Window w,
  186.                 Size winHeightWidth,
  187.                 Point  winTopLeft,
  188.                 WindowStateData lastModstate) {
  189.  
  190.                 WindowStateData data = this;
  191.                 data.State = w.WindowState;
  192.                
  193.                
  194.                 if(w.WindowState == System.Windows.WindowState.Normal) {
  195.                     data.Width = w.Width;
  196.                     data.Height = w.Height;
  197.                     data.Top = w.Top;
  198.                     data.Left = w.Left;
  199.                 }
  200.                 else if(w.WindowState == System.Windows.WindowState.Maximized) {
  201.                     data.Width = winHeightWidth.Width;
  202.                     data.Height = winHeightWidth.Height;
  203.                     data.Top = winTopLeft.X;
  204.                     data.Left = winTopLeft.Y;
  205.                 }
  206.                 else if(w.WindowState == System.Windows.WindowState.Minimized) {
  207.                     data.Width = lastModstate.Width;
  208.                     data.Height = lastModstate.Height;
  209.                     data.Top = lastModstate.Top;
  210.                     data.Left = lastModstate.Left;
  211.                 }
  212.             }
  213.  
  214.             [XmlElement("AdditionalData")]
  215.             public SerializableDictionary<string,object> AdditionalData {
  216.                 get {
  217.                     if(_additionalData == null)
  218.                         _additionalData = new SerializableDictionary<string,object>();
  219.                     return _additionalData;
  220.                 }
  221.                 set { _additionalData = value; }
  222.             }
  223.  
  224.  
  225.             public double Width {
  226.                 get;
  227.                 set;
  228.             }
  229.             public double Height {
  230.                 get;
  231.                 set;
  232.             }
  233.             public double Top {
  234.                 get;
  235.                 set;
  236.             }
  237.             public double Left {
  238.                 get;
  239.                 set;
  240.             }
  241.             public WindowState State {
  242.                 get;
  243.                 set;
  244.             }
  245.             public bool AllowMaximized {
  246.                 get;
  247.                 set;
  248.             }
  249.  
  250.             public void Reset() {
  251.                 Top = -1;
  252.                 Left = -1;
  253.                 Height = 400;
  254.                 Width = 600;
  255.                 State = WindowState.Normal;
  256.                 AllowMaximized = true;
  257.             }
  258.             public WindowStateData Copy() {
  259.                 WindowStateData copied = new WindowStateData();
  260.                 copied.Width = this.Width;
  261.                 copied.Height = this.Height;
  262.                 copied.Top = this.Top;
  263.                 copied.Left = this.Left;
  264.                 copied.State = this.State;
  265.                 copied.AllowMaximized = this.AllowMaximized;
  266.                 return copied;
  267.             }
  268.  
  269.             public WindowStateData() {
  270.                 Reset();
  271.             }
  272.             public override string ToString() {
  273.                 return string.Format("w:{0:N0} h:{1:N0} t:{2:N0} l:{3:N0}",Width,Height,Top,Left);
  274.             }
  275.         }
  276.     }
  277.  
  278.     internal class XmlHelpers {
  279.  
  280.         public static object CopyObject(object toCopy) {
  281.             return CopyObject<object>(toCopy);
  282.         }
  283.         /// <summary>
  284.         /// Copies an object using the XmlSerilizer class
  285.         /// </summary>
  286.         /// <typeparam name="T"></typeparam>
  287.         /// <param name="toCopy"></param>
  288.         /// <returns>New object</returns>
  289.         public static T CopyObject<T>(T toCopy) {
  290.             if(toCopy == null)
  291.                 throw new ArgumentNullException("toCopy");
  292.  
  293.             using(MemoryStream memoryStream = new MemoryStream()) {
  294.                 XmlSerializer xs = new XmlSerializer(toCopy.GetType());
  295.                 XmlSerializerNamespaces xmlNamespace = new XmlSerializerNamespaces();
  296.  
  297.                 xmlNamespace.Add(string.Empty,string.Empty);
  298.                 xs.Serialize(memoryStream,toCopy,xmlNamespace);
  299.                 return (T)xs.Deserialize(memoryStream);
  300.             }
  301.         }
  302.         /// <summary>
  303.         /// Method to reconstruct an Object from XML string
  304.         /// </summary>
  305.         /// <param name="pXmlizedString"></param>
  306.         /// <returns></returns>
  307.         public static Object DeserializeObject(String pXmlizedString,Type objectType) {
  308.             try {
  309.                 XmlSerializer xs = new XmlSerializer(objectType);
  310.                 using(MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString))) {
  311.                     XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream,Encoding.UTF8);
  312.                     return xs.Deserialize(memoryStream);
  313.                 }
  314.             }
  315.             catch {
  316.                 throw;
  317.             }
  318.         }
  319.         public static bool TryDeserializeObject(string xmlString,Type objType,out object theObject) {
  320.             try {
  321.                 theObject = DeserializeObject(xmlString,objType);
  322.                 return true;
  323.             }
  324.             catch {
  325.                 theObject = null;
  326.                 return false;
  327.             }
  328.         }
  329.  
  330.         public static String SerializeObject(Object pObject) {
  331.             return SerializeObject(pObject,pObject.GetType());
  332.         }
  333.  
  334.         public static String SerializeObject(Object pObject,Type objectType) {
  335.             try {
  336.                 String XmlizedString = null;
  337.  
  338.                 using(MemoryStream memoryStream = new MemoryStream()) {
  339.                     XmlSerializer xs = new XmlSerializer(objectType);
  340.  
  341.                     XmlSerializerNamespaces xmlNamespace = new XmlSerializerNamespaces();
  342.                     xmlNamespace.Add(string.Empty,string.Empty);
  343.  
  344.                     xs.Serialize(memoryStream,pObject,xmlNamespace);
  345.                     XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
  346.                 }
  347.                 return XmlizedString;
  348.             }
  349.             catch {
  350.                 throw;
  351.             }
  352.         }
  353.  
  354.         public static bool TrySerializeObject(object pObject,Type objectType,out string xmlString) {
  355.             try {
  356.                 xmlString = SerializeObject(pObject,objectType);
  357.                 return true;
  358.             }
  359.             catch {
  360.                 xmlString = null;
  361.                 return false;
  362.             }
  363.         }
  364.  
  365.         public static void SaveObjectToFile(object obj,string path) {
  366.             File.WriteAllText(path,SerializeObject(obj,obj.GetType()));
  367.         }
  368.  
  369.         public static T ReadObjectFromFile<T>(string path) {
  370.             return (T)XmlHelpers.DeserializeObject(File.ReadAllText(path),typeof(T));
  371.         }
  372.  
  373.         public static object ReadObjectFromFile<T>(string path,Type objType) {
  374.             return XmlHelpers.DeserializeObject(File.ReadAllText(path),objType);
  375.         }
  376.         /// <summary>
  377.         /// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
  378.         /// </summary>
  379.         /// <param name="characters">Unicode Byte Array to be converted to String</param>
  380.         /// <returns>String converted from Unicode Byte Array</returns>
  381.         private static String UTF8ByteArrayToString(Byte[] characters) {
  382.             UTF8Encoding encoding = new UTF8Encoding();
  383.             String constructedString = encoding.GetString(characters);
  384.             return (constructedString);
  385.         }
  386.  
  387.         /// <summary>
  388.         /// Converts the String to UTF8 Byte array and is used in De serialization
  389.         /// </summary>
  390.         /// <param name="pXmlString"></param>
  391.         /// <returns></returns>
  392.         private static Byte[] StringToUTF8ByteArray(String pXmlString) {
  393.             UTF8Encoding encoding = new UTF8Encoding();
  394.             Byte[] byteArray = encoding.GetBytes(pXmlString);
  395.             return byteArray;
  396.         }
  397.     }
  398.  
  399.     [XmlRoot("dictionary")]
  400.     [Serializable]
  401.     public class SerializableDictionary<TKey,TValue>
  402.         :Dictionary<TKey,TValue>,IXmlSerializable {
  403.  
  404.         #region Constructor
  405.         public SerializableDictionary() {
  406.         }
  407.  
  408.         public SerializableDictionary(IDictionary<TKey,TValue> dictionary)
  409.             : base(dictionary) {
  410.         }
  411.  
  412.         #endregion
  413.  
  414.         #region IXmlSerializable Members
  415.  
  416.         public System.Xml.Schema.XmlSchema GetSchema() {
  417.             return null;
  418.         }
  419.  
  420.         public void ReadXml(System.Xml.XmlReader reader) {
  421.             XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
  422.             XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
  423.  
  424.             bool wasEmpty = reader.IsEmptyElement;
  425.  
  426.             reader.Read();
  427.  
  428.             if(wasEmpty)
  429.                 return;
  430.  
  431.             while(reader.NodeType != System.Xml.XmlNodeType.EndElement) {
  432.                 reader.ReadStartElement("item");
  433.                 reader.ReadStartElement("key");
  434.                 TKey key = (TKey)keySerializer.Deserialize(reader);
  435.                 reader.ReadEndElement();
  436.  
  437.                 reader.ReadStartElement("value");
  438.                 TValue value = (TValue)valueSerializer.Deserialize(reader);
  439.                 reader.ReadEndElement();
  440.  
  441.                 this.Add(key,value);
  442.  
  443.                 reader.ReadEndElement();
  444.                 reader.MoveToContent();
  445.             }
  446.  
  447.             reader.ReadEndElement();
  448.         }
  449.  
  450.         public void WriteXml(System.Xml.XmlWriter writer) {
  451.             XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
  452.             XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
  453.  
  454.             foreach(TKey key in this.Keys) {
  455.                 writer.WriteStartElement("item");
  456.  
  457.                 writer.WriteStartElement("key");
  458.                 keySerializer.Serialize(writer,key);
  459.                 writer.WriteEndElement();
  460.  
  461.                 writer.WriteStartElement("value");
  462.                 TValue value = this[key];
  463.                 valueSerializer.Serialize(writer,value);
  464.                 writer.WriteEndElement();
  465.  
  466.                 writer.WriteEndElement();
  467.             }
  468.         }
  469.  
  470.         #endregion
  471.     }
  472. }
Advertisement
Add Comment
Please, Sign In to add comment