How to: Implement Custom Context Navigation

The Navigation System supports context navigation. You can track the process of creating navigation items in the navigation control and add custom navigation items. This topic demonstrates how to implement custom context navigation in your applications. A Window Controller will be implemented. This Controller will add the "Task-Based Help" child navigation items, each of which will contain items invoking Detail Views displaying various help documents.

ContextNavigationCustomHowTo

Note

Mobile applications do not support the dynamically creation of navigation items, so the approach described in this topic cannot be implemented in the Mobile platform.

Tip

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=E1843.

To implement the sample custom context navigation, perform the following steps.

  1. Define the HelpDocument business class. This is the class that will represent help documents.
  2. Implement a custom Window Controller. It will contain the custom context navigation logic that will handle the ShowNavigationItemController.NavigationItemCreated. The event handler must create a child navigation item titled "Task-Based Help" and its corresponding child nodes pointing to appropriate help documents. Note that each help document will be associated with a particular business class. And a created navigation item can point to a View of a business class that does not have associated documents. In this instance, the "Task-Based Help" navigation item should not be created.

Define the HelpDocument Business Class

The HelpDocument business class is comprised of three properties.

  • Title - represents a document's title.
  • Text - holds the actual text contained in the document. A help document's text can be very long, so this property should be decorated with the Size[-1] attribute (see Data Annotations in Data Model).
  • ObjectType - each document will be associated with a business class. So only help topics relevant to a specific business class will be displayed. The ObjectType property holds the associated business class' type. Since this property is of the Type type, a custom value converter must be implemented (see ValueConverter) for the property to be stored properly in the database.
using DevExpress.ExpressApp.Utils;
//...
[DefaultClassOptions, ImageName("BO_Report")]
public class HelpDocument : BaseObject {
    public HelpDocument(Session session) : base(session) { }
    [DevExpress.Xpo.ValueConverter(typeof(TypeToStringConverter ))]
    public Type ObjectType {
        get { return GetPropertyValue<Type>("ObjectType"); }
        set { SetPropertyValue<Type>("ObjectType", value); }
    }
    public string Title {
        get { return GetPropertyValue<string>("Title"); }
        set { SetPropertyValue<string>("Title", value); }
    }
    [Size(-1)]
    public string Text {
        get { return GetPropertyValue<string>("Text"); }
        set { SetPropertyValue<string>("Text", value); }
    }
}

Implement a Custom Window Controller

The custom Controller must only be activated for the main Window, since only main Window Templates contain the navigation Action Container (see Navigation System). To implement the custom context navigation logic, subscribe to the ShowNavigationItemController's NavigationItemCreated event. Do not forget to unsubscribe from the event to prevent memory leaks.

using DevExpress.ExpressApp.SystemModule;
//...
public class TaskBasedHelpController : WindowController {
    private ShowNavigationItemController navigationController;
    protected override void OnFrameAssigned() {
        UnsubscribeFromEvents();
        base.OnFrameAssigned();
        navigationController =
            Frame.GetController<ShowNavigationItemController>();
        if(navigationController != null) {
            navigationController.NavigationItemCreated += 
                navigationItemCreated;
        }
    }
    private void UnsubscribeFromEvents() {
        if(navigationController != null) {
            navigationController.NavigationItemCreated -= 
                navigationItemCreated;
            navigationController = null;
        }
    }
    protected override void Dispose(bool disposing) {
        UnsubscribeFromEvents();
        base.Dispose(disposing);
    }
}

Handle the NavigationItemCreated event

The NavigationItemCreated event occurs after a navigation item has been created in the navigation control. You will need to track the creation of navigation items in the event handler. Since not every navigation item points to a View, check whether a particular NavigationItem node's View property is set. If it is, check whether help documents for a particular business class exist. If there are existing help documents, create the "Task-Based Help" child navigation item and populate it with child nodes corresponding to these existing help documents. Additionally, create a read-only HelpDocument_DetailView_FewColumns Detail View via the Model Editor. This View will be used to display help documents.

using System.Collections.Generic;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
//...
public class TaskBasedHelpController : WindowController {
    //...
    void navigationItemCreated(object sender, NavigationItemCreatedEventArgs e) {
        ChoiceActionItem navigationItem = e.NavigationItem;
        IModelObjectView viewNode = ((IModelNavigationItem)e.NavigationItem.Model).View as 
            IModelObjectView;
        if (viewNode != null) {
            ITypeInfo objectTypeInfo = XafTypesInfo.Instance.FindTypeInfo(viewNode.ModelClass.Name);
            if (objectTypeInfo != null) {
                CriteriaOperator docCriteria = 
                    CriteriaOperator.Parse("ObjectType == ?", objectTypeInfo.Type);
                IObjectSpace myObjectSpace = Application.CreateObjectSpace(typeof(HelpDocument));
                IList<HelpDocument> docs = myObjectSpace.GetObjects<HelpDocument>(docCriteria);
                if (docs.Count > 0) {
                    ChoiceActionItem docsGroup = new ChoiceActionItem(
                        "CustomDocuments", "Task-Based Help", null) { ImageName = "BO_Report" };
                    navigationItem.Items.Add(docsGroup);
                    foreach (HelpDocument doc in docs) {
                        ViewShortcut shortcut = new ViewShortcut(typeof(HelpDocument), 
                            doc.Oid.ToString(), "HelpDocument_DetailView_FewColumns");
                        ChoiceActionItem docItem = new ChoiceActionItem(
                            doc.Oid.ToString(), doc.Title, shortcut) 
                            { ImageName = "Navigation_Item_Report" };
                        docsGroup.Items.Add(docItem);
                    }
                }
            }
        }
    }
}
See Also