Skip to content

Data Manager and Control Context Data

REghZy edited this page Aug 24, 2025 · 2 revisions

Data Manager

This class manages local and inherited context data of controls. The interface IContextData is used to query context from a key.

Data Keys

Data keys are just a wrapper for a string. We use the DataKey<T> class, because it allows associating a type with the key, which gives us type safety.

Local Context

This is context data stored in the control itself. It can be accessed via the method DataManager.GetContextData(). Local Context is similar to the DataContext property, except whereas data context is a single object, context data is a dictionary of key-value entries.

Inherited Context

This is the merged local context of a control and its visual parents. The fully merged context data is called the Inherited Context, and is accessible via DataManager.GetFullContextData().

The entries are merged top-to-bottom, and descendants have priority over the value of duplicate entries (as in, the key already added to the dictionary during merge process)

This process is fully automatic. When the local context of any control changes, the inherited context becomes invalidated, and the event InheritedContextChangedEvent is fired on every visual descendent of the control whose local context changes.

Warning

When a control is attached to a visual tree, the current inherited data is invalidated and InheritedContextChangedEvent is invoked. However, this does not happen when a control is detached from the visual tree, which can lead to undefined behaviour with detached controls, however, it massively improves the performance of auto-invalidation, and is therefore worth it.

If you absolutely need to use inherited context of controls not attached to the VT, you can either invoke InvalidateInheritedContext and then access it, or use EvaluateContextDataRaw() (which is what GetFullContextData() calls when the data was invalidated)

Suspending auto-invalidation when adding/removing multiple entries

If you want to add or remove multiple data keys, it's more performant to start a multi-change operation.

using MultiChangeToken change = DataManager.GetContextData(theControl).BeginChange();
change.Context.Set(MyDataKeys.Key1, obj1).Set(MyDataKeys.Key2, obj2);
change.Context.Set(ISomeInterface.DataKey, theObj);
change.Context.Remove(MyDataKeys.RareDataKey);

Modifications do not actually modify theControl's local context, but instead, are stored temporarily.

Once change.Dispose() is called, it decreases the multi-change counter of theControl's local context, and when it becomes 0, the modifications are applied to the local context and DataManager.InvalidateInheritedContext is invoked

Clone this wiki locally