Skip to content

Implementing a Context Interface

Gary edited this page Mar 10, 2015 · 2 revisions

Table of Contents

You implement a context interface by creating a class that implements all the context (and other) interfaces you want to use. The objects created from this class can later be obtained from the ContextRegistry, which tracks the existing context objects. These objects can then be cast to objects implementing the various interfaces.

Various context interfaces have various points of view about the context. Hence there is a great variety in these implementations.

Implementing Needed Interfaces

Make sure you implement all the appropriate context (and other) interfaces required for a class. For example, the StandardEditCommands component has a Paste() method that gets the active context from the ContextRegistry, adapted to an IInstancingContext interface. It then adapts it to an ITransactionContext. The underlying context class must also implement ITransactionContext for this to work.

public void Paste()
{
    IInstancingContext instancingContext = m_contextRegistry.GetActiveContext<IInstancingContext>();
    if (instancingContext != null &&
        instancingContext.CanInsert(Clipboard))
    {
        ITransactionContext transactionContext = instancingContext.As<ITransactionContext>();
        transactionContext.DoTransaction(
            delegate
            {
                instancingContext.Insert(Clipboard);
            }, CommandInfo.EditPaste.MenuText);

        OnPasted(EventArgs.Empty);
    }
}

To meet this requirement, a class could derive from EditingContext and also implement IInstancingContext. EditingContext derives from HistoryContext, which derives from TransactionContext, which implements ITransactionContext.

For example, the ATF Simple DOM Editor Sample uses the StandardEditCommands component. It implements several context handling classes, such as the EventContext class, which does what's needed:

public class EventContext : EditingContext,
    IListView,
    IItemView,
    IObservableContext,
    IInstancingContext,
    IEnumerableContext

Related Context Interfaces

Some context interfaces go together. For instance, if you implement a class derived from SelectionContext, you probably want to implement IInstancingContext as well. If you can select objects, you can typically edit them, too, and IInstancingContext provides editing methods. For more details, see Instancing In ATF.

For example, the LayeringContext class derives from SelectionContext and implements IInstancingContext as well as other context interfaces:

public abstract class LayeringContext : SelectionContext,
    IInstancingContext,
    IHierarchicalInsertionContext,
    ILayeringContext,
    IObservableContext,
    INamingContext

Variations on Implementing a Context Interface

An application determines its contexts, and a context interface's implementation can be wildly different from application to application.

For example, here is a partial implementation of IInstancingContext for ATF Simple DOM Editor Sample:

public bool CanCopy()
{
    return Selection.Count > 0;
}
...
public object Copy()
{
    IEnumerable<DomNode> resources = Selection.AsIEnumerable<DomNode>();
    List<object> copies = new List<object>(DomNode.Copy(resources));
    return new DataObject(copies.ToArray());
}

Here is the corresponding implementation in ATF Timeline Editor Sample:

public bool CanCopy()
{
    return Selection.Count > 0;
}
...
public object Copy()
{
    object[] selection = Selection.GetSnapshot();

    // Cut + Paste needs to know the original tracks of the cut objects.
    m_copyObjToTrack = new Dictionary<ITimelineObject, ITrack>(selection.Length);
    foreach (ITimelineObject source in selection.AsIEnumerable<ITimelineObject>())
    {
        ITrack sourceTrack;
        IGroup sourceGroup;
        GetTrackAndGroup(source, out sourceTrack, out sourceGroup);
        if (sourceTrack != null)
            m_copyObjToTrack[source] = sourceTrack;
    }

    return new DataObject(selection);
}

These examples are taken from their samples' versions of an editing context class, which both derive from EditingContext and implement IInstancingContext.

The CanCopy() method is identical in both samples. Both use the EditingContext.Selection property and check that its Count property is positive. The Copy() methods, on the other hand, look totally different. Copy() depends on the nature of selectable objects — the data model — which is quite different in the two samples.

SimpleDOMEditor Examples

The ATF Simple DOM Editor Sample implements several context interfaces. For programming details, see Working With Contexts.

Topics in this section

Clone this wiki locally