A storage for properties and events of a class
Remarks: This is used by Widget object to minimize the footprint of each instance. For example, the Control class has around 20 events, each would take up to 4 bytes on a 32 bit system for a total overhead of 80 bytes per instance. Most of the events won't be handled on most controls, so using a dictionary can dramatically reduce the size. This can also be used for rarely used properties that do not need to be extremely performant when getting or setting the value.

Constructors

PropertyStore

#
public PropertyStore(object parent)
Initializes a new instance of the PropertyStore class.

Properties

Parent

#
public object Parent { get; }
Gets the parent object that this property store is attached to
Remarks: This is used to attach/remove events
The parent object

Methods

AddEvent

#
public void AddEvent(object key, Delegate value)
Adds a generic event delegate with the specified key
Remarks: This should be called in an event's add accessor. If you are adding a handler-based event, call AddHandlerEvent(string, Delegate) instead, which will automatically tell the handler that it needs to be wired up. You can use any subclass of EventArgs for the type of event handler To trigger the event, use TriggerEvent<T>(object, object, T).
key (object)Key of the event to add to
value (Delegate)Delegate to add to the event
Example implementation of a generic event
static readonly object MySomethingEventKey = new object();

public event EventHandler<EventArgs> MySomething
{
	add { Properties.AddEvent(MySomethingEvent, value); }
	remove { Properties.RemoveEvent(MySomethingEvent, value); }
}

AddHandlerEvent

#
public void AddHandlerEvent(string key, Delegate value)
Adds a handler-based event delegate with the specified key
Remarks: This should be called in an event's add accessor. This is used for any event that should be triggered by the platform handler. This will call HandleEvent with the specified key for the first subscription to the event. You can use any subclass of EventArgs for the type of event handler To trigger the event, use TriggerEvent<T>(object, object, T)
key (string)Key of the event to add to
value (Delegate)Delegate to add to the event
Example implementation of a handler-triggered event
public const string MySomethingEvent = "MyControl.MySomething";

public event EventHandler<EventArgs> MySomething
{
	add { Properties.AddHandlerEvent(MySomethingEvent, value); }
	remove { Properties.RemoveHandlerEvent(MySomethingEvent, value); }
}

Create<T>

#
public T Create<T>(object key, Func<T> create)
Gets a value from the property store with the specified key of a concrete type, and creates a new instance if it doesn't exist yet.
key (object)Key of the property to get
create (Func<T>)Delegate to create the object, if it doesn't already exist
Value of the property with the given key, or a new instance if not already added

Create<T>

#
public T Create<T>(object key)
Gets a value from the property store with the specified key of a concrete type, and creates a new instance if it doesn't exist yet.
key (object)Key of the property to get
Value of the property with the given key, or a new instance if not already added

Get<T>

#
public T Get<T>(object key, Func<T> defaultValue)
Gets a value from the property store with the specified key of a concrete type
key (object)Key of the property to get
defaultValue (Func<T>)Value to return when the specified property is not found in the dictionary
Value of the property with the given key, or defaultValue if not found

Get<T>

#
public T Get<T>(object key, T defaultValue = default(T))
Gets a value from the property store with the specified key of a concrete type
key (object)Key of the property to get
defaultValue (T = null)Value to return when the specified property is not found in the dictionary
Value of the property with the given key, or defaultValue if not found

GetCommand

#
public ICommand GetCommand(object key)
Gets the command instance for the specified property key.

RemoveEvent

#
public void RemoveEvent(object key, Delegate value)
Removes the event delegate with the specified key
Remarks: Use this in the remove accessor of your event. See AddEvent(object, Delegate) and AddHandlerEvent(string, Delegate) for examples.
key (object)Key of the event to remove
value (Delegate)Delegate to remove from the event

RemoveHandlerEvent

#Since v2.12
public void RemoveHandlerEvent(string key, Delegate value)
Removes a handler-based event delegate with the specified key, telling the handler to stop listening once the last subscriber is gone.
Remarks: Use this in the remove accessor of an event added with AddHandlerEvent(string, Delegate) when the platform holds onto something worth giving back while the event is attached, such as a system wide hook. RemoveEvent(object, Delegate) leaves the event attached for the life of the widget, which is fine and cheaper for the vast majority of events. The handler is only told once nothing is subscribed any more, and never for an event that is attached because the widget overrides its On[Event] method, since that has to keep firing. A handler that can't detach the event says so, and it stays attached.
key (string)Key of the event to remove
value (Delegate)Delegate to remove from the event

Set<T>

#
public bool Set<T>(object key, T value, Action propertyChanged, T defaultValue = default(T))
Set the value for the specified property key, calling the propertyChanged delegate if it has changed.
Remarks: This is useful when creating properties that need to trigger changed events without having to write boilerplate code.
key (object)Key of the property to set.
value (T)Value for the property.
propertyChanged (Action)Property changed event handler to raise if the property value has changed.
defaultValue (T = null)Default value of the property to compare when removing the key
true if the property was changed, false if not
public class MyForm : Form
{
	static readonly MyPropertyKey = new object();

	public bool MyProperty
	{
		get { return Properties.Get<bool>(MyPropertyKey); }
		set { Properties.Set(MyPropertyKey, value, OnMyPropertyChanged); }
	}

	public event EventHandler<EventArgs> MyPropertyChanged;
	
	protected virtual void MyPropertyChanged(EventArgs e)
	{
		if (MyPropertyChanged != null)
			MyPropertyChanged(this, e);
	}
}

Set<T>

#
public bool Set<T>(object key, T value, PropertyChangedEventHandler propertyChanged, T defaultValue = default(T), string propertyName = null)
Set the value for the specified property key, raising the propertyChanged handler if it has changed.
Remarks: This is useful when creating properties that need to trigger changed events without having to write boilerplate code.
key (object)Key of the property to set.
value (T)Value for the property.
propertyChanged (PropertyChangedEventHandler)Property changed event handler to raise if the property value has changed.
defaultValue (T = null)Default value of the property to compare when removing the key
propertyName (string = null)Name of the property, or omit to get the property name from the caller.
true if the property was changed, false if not
public class MyForm : Form, INotifyPropertyChanged
{
	static readonly MyPropertyKey = new object();

	public bool MyProperty
	{
		get { return Properties.Get<bool>(MyPropertyKey); }
		set { Properties.Set(MyPropertyKey, value, PropertyChanged); }
	}

	public event PropertyChangedEventHandler PropertyChanged;
}

Set<T>

#
public void Set<T>(object key, T value, T defaultValue = default(T))
Set the value for the specified property key, removing the value from the dictionary if it is the default value of T.
Remarks: This can be used as an optimized way to set the value in the dictionary as if the value set equal to the defaultValue (e.g. null for reference types, false for bool, 0 for int, etc), then it will be removed from the dictionary instead of just set to the value, reducing memory usage. The Get<T>(object, T) should be passed the same default when retrieving the parameter value.
key (object)Key of the property to set.
value (T)Value for the property.
defaultValue (T = null)Value of the property when it should be removed from the dictionary. This should match what is passed to Get<T>(object, T) when getting the value.

SetCommand

#
public void SetCommand(object key, ICommand value, Action<bool> setEnabled, Action<EventHandler<EventArgs>> addExecute, Action<EventHandler<EventArgs>> removeExecute, Func<object> getParameter)
Sets an ICommand value for the specified property key.
key (object)Key of the property to set
value (ICommand)Command instance
setEnabled (Action<bool>)Delegate to set the widget as enabled when the command state changes.
addExecute (Action<EventHandler<EventArgs>>)Delegate to attach the execute event handler when the widget invokes the command.
removeExecute (Action<EventHandler<EventArgs>>)Delegate to detach the execute event handler.
getParameter (Func<object>)Delegate to get the parameter to pass to the command

TriggerEvent<T>

#
public void TriggerEvent<T>(object key, object sender, T args)
Triggers an event with the specified key
Remarks: Call this in your OnMyEvent(EventArgs) method to trigger the event if it has been subscribed to. This can handle events that have any type of EventArgs.
key (object)Key of the generic or handler event
sender (object)Object sending the event (usually 'this')
args (T)Arguments for the event
This shows how to trigger either a generic event or handler-triggered event:
protected virtual void OnMySomething(EventArgs e)
{
	Properties.TriggerEvent(MySomethingEventKey, this, e);
}

TrySet<T>

#
public bool TrySet<T>(object key, T value, T defaultValue = default(T))
Set the value for the specified property key, removing the value from the dictionary if it is the default value of T.
Remarks: This can be used as an optimized way to set the value in the dictionary as if the value set equal to the default value. (e.g. null for reference types, false for bool, 0 for int, etc), then it will be removed from the dictionary instead of just set to the value, reducing memory usage.
key (object)Key of the property to set.
value (T)Value for the property.
defaultValue (T = null)Value of the property when it should be removed from the dictionary. This should match what is passed to Get<T>(object, T) when getting the value.
true if the value was changed, false otherwise.

UnbindCommand

#Since v2.11
public void UnbindCommand(object key)
Unbinds the command associated with the specified key, removing its registration.
Remarks: If the command associated with the specified key is found, it will be unregistered, allowing for cleanup of resources or state related to the command.
key (object)The key used to identify the command to be unbound. Cannot be null.

UpdateCommandCanExecute

#
public void UpdateCommandCanExecute(object key)
Updates the command's execute status, typically when the CommandParameter changes.