Click here to Skip to main content
12,354,086 members (71,255 online)
Click here to Skip to main content

Stats

89.6K views
529 downloads
37 bookmarked
Posted

WPF Control State Persistency

, 9 Jun 2007
This article describes how to store and restore WPF's elements state, such as position, size, etc.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.ComponentModel;

namespace Tomers.WPF.State
{
	public enum ElementStateMode
	{
		Memory,
		Persist
	}

	public class ElementState : DependencyObject
	{
		#region Fields

		private readonly string				_uid;
		private readonly ElementStateMode	_mode;
		private readonly Type				_type;

		/// <stringValue>Holds the state of each element property</stringValue>
		private readonly Dictionary<DependencyProperty, object> _state =
			new Dictionary<DependencyProperty, object>();

		#endregion

		#region Initializers

		internal ElementState(DependencyObject element)
		{
			this._uid	= GetUId(element);
			this._mode	= GetMode(element);
			this._type	= element.GetType();
		}

		#endregion

		#region Attached Properties

		#region Mode Property

		/// <stringValue>Identifies the Mode dependency property</stringValue>
		public static readonly DependencyProperty ModeProperty =
			DependencyProperty.RegisterAttached("Mode", typeof(ElementStateMode), typeof(ElementState),
			new PropertyMetadata(ElementStateMode.Memory));

		public static void SetMode(DependencyObject element, ElementStateMode value)
		{
			element.SetValue(ModeProperty, value);
		}

		public static ElementStateMode GetMode(DependencyObject element)
		{
			return (ElementStateMode)element.GetValue(ModeProperty);
		}

		#endregion

		#region UId Property

		/// <stringValue>Identifies the UId dependency property</stringValue>
		public static readonly DependencyProperty UIdProperty =
			DependencyProperty.RegisterAttached("UId", typeof(string), typeof(ElementState),
			new PropertyMetadata(string.Empty));

		public static void SetUId(DependencyObject element, string value)
		{
			element.SetValue(UIdProperty, value);
		}

		public static string GetUId(DependencyObject element)
		{
			return (string)element.GetValue(UIdProperty);
		}

		#endregion

		#endregion

		#region Properties

		internal string UId
		{
			get { return _uid; }
		}

		internal ElementStateMode Mode
		{
			get { return _mode; }
		}

		internal Type Type
		{
			get { return _type; }
		} 

		#endregion

		#region Operations

		internal new object GetValue(DependencyProperty property)
		{
			if (!HasValue(property))
			{
				throw new ArgumentException(string.Format("There is no value for property name {0}", property.Name));
			}
			return _state[property];
		}

		internal bool HasValue(DependencyProperty property)
		{
			return _state.ContainsKey(property);
		}

		internal object AddValue(DependencyProperty property, object value)
		{
			if (_state.ContainsKey(property))
			{
				return _state[property];
			}
			else
			{
				// The property is not exist
				if (Mode == ElementStateMode.Persist &&
					ElementStateOperations.Persistency.Contains(UId, property.Name))
				{
					string stringValue = ElementStateOperations.Persistency.GetValue(UId, property.Name);
					value = ElementStateExtension.ConvertFromString(Type, property, stringValue);
				}
				_state.Add(property, value);
			}
			return value;
		}

		internal void UpdateValue(DependencyProperty property, object value)
		{
			if (!_state.ContainsKey(property))
			{
				throw new ArgumentException(string.Format("Property name {0} is not in state", property.Name));
			}
			// Override the old value
			_state[property] = value;
			string stringValue = ElementStateExtension.ConvertToString(Type, property, value);
			ElementStateOperations.Persistency.Update(UId, property.Name, stringValue);
		}

		internal void BindProperty(DependencyObject element, DependencyProperty property)
		{
			Binding binding = new Binding();
			binding.Mode = BindingMode.OneWayToSource;
			binding.Converter = new ValueConverter(this);
			binding.ConverterParameter = property;
			binding.Source = this;
			binding.Path = new PropertyPath(".");
			BindingOperations.SetBinding(element, property, binding);
		}

		#endregion

		#region Types

		class ValueConverter : IValueConverter
		{
			private ElementState _state;

			public ValueConverter(ElementState state)
			{
				this._state = state;
			}

			#region IValueConverter Members

			public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
			{
				throw new NotSupportedException();
			}

			public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
			{
				DependencyProperty dp = (DependencyProperty)parameter;
				_state.UpdateValue(dp, value);
				return value;
			}

			#endregion
		}

		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Tomer Shamam
Architect CodeValue
Israel Israel
Tomer Shamam is a Software Architect and a UI Expert at CodeValue, the home of software experts, based in Israel (http://codevalue.net). Tomer is a speaker in Microsoft conferences and user groups, and in-house courses. Tomer has years of experience in software development, he holds a B.A degree in computer science, and his writings appear regularly in the Israeli MSDN Pulse, and other popular developer web sites such as CodePlex and The Code Project. About his thoughts and ideas you can read in his blog (http://blogs.microsoft.co.il/blogs/tomershamam).

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 10 Jun 2007
Article Copyright 2007 by Tomer Shamam
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid