Deferred Load

  • 7 minutes to read

If your view contains many documents, you may want to use the deferred load feature. The main idea of the deferred load is that you initially create "empty" documents and provide content for them later, via an event that fires when an empty document is about to be displayed. The deferred load approach allows you to significantly reduce the application start-up initialization time, but navigation through documents will be a little slower compared to the direct content loading approach via the BaseView.AddDocument method.

Documents must be empty (i.e., have no content) to trigger the deferred load mechanism.

At runtime, you can create empty documents via the BaseView.AddDocument method overload without the Control parameter. At design time, you can create empty documents via the Document Manager Designer. Switch to the 'Documents' tab and add documents via the "Add New Document" button.

DocumentManager - Tasks

DocumentManager - Designer

To specify the content (of any control) for an empty document, handle the BaseView.QueryControl event. This event is the first one triggered by the deferred load mechanism when an empty document is about to be displayed. It fires on application start-up (when displaying the first "empty" document), and each time an end-user activates another "empty" document (for instance, by clicking a tab header in the TabbedView). To set the content for the document, assign a control to the event's Control parameter, as shown below.


private void windowsUIView1_QueryControl(object sender, DevExpress.XtraBars.Docking2010.Views.QueryControlEventArgs e) {
    if(e.Document == document1)
         e.Control = new UserControl1();
    if(e.Document == document2)
         e.Control = new UserControl2();
}

After a document's content has been displayed, the BaseView.ControlShown event fires.

By default, the deferred load mechanism persists the document content when the document is unselected. For instance, when switching from one tab to another in the TabbedView, the previously activated tab's contents are not destroyed by default. In the NativeMdiView, document content is never destroyed.

If you want to unbind a document's content, handle the BaseView.ControlReleasing event and set the event's KeepControl parameter to false. For this document, the BaseView.QueryControl event will repeatedly fire when the document is activated again. By default, unbound content is automatically destroyed.

When handling the BaseView.ControlReleasing event, you also have the option to unbind a document from its content without destroying the content itself so you can pass it to another document. This can be accomplished by setting the event's KeepControl and DisposeControl parameters to false.

After a control has been unbound from its parent document, the BaseView.ControlReleased event is raised.

The diagram below demonstrates this event sequence.

DocumentManager - Deferred Load Scheme

The following code from DevExpress BarTutorials ('Deferred Load' demo) illustrates how to use the BaseView.QueryControl and BaseView.ControlReleasing events:


public partial class DocumentManagerDeferredLoadDocuments : TutorialControl {
    public DocumentManagerDeferredLoadDocuments() {
        InitializeComponent();
    }
    int i = 0;
    //A string array used to fill document content
    string[] texts = new string[]{ 
        "Vestibulum sem nunc, cursus sit amet placerat id, scelerisque at tortor. Nullam sit amet felis eros, ac imperdiet quam. Aliquam eu ipsum dui.",
        "Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur sit amet sapien metus, eget pharetra velit.",
        "Duis sagittis iaculis nisl, sit amet ultricies lectus porttitor nec. Suspendisse id venenatis sem. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",
        "Aliquam erat volutpat. Ut sit amet purus. Nullam a lectus. Duis in elit. Ut nonummy est pellentesque eros. Sed ultrices convallis nulla. Phasellus urna lorem, mattis a, luctus congue, dictum in, nunc."
        };
    //Creates a label, sets this text via the GetText function, places the label onto a Panel object and sets this panel as the document content.
    void tabbedView_QueryControl(object sender, QueryControlEventArgs e) {
        Panel child = new Panel();
        child.Padding = new Padding(16);
        LabelControl label = new LabelControl();
        label.Text = GetText(i);
        label.AutoSizeMode = LabelAutoSizeMode.Vertical;
        child.Controls.Add(label);
        label.Dock = DockStyle.Fill;
        e.Control = child;
        i++;
        }
    //Gets a specific string from the 'texts' array. The Sleep method emulates the time required to load content for complex documents.
    string GetText(int i) {
        System.Threading.Thread.Sleep(1000);
        return string.Format("{0} {1}", texts[i % texts.Length], texts[(i + 2) % texts.Length]);
        }
    //Prevents unselected documents from being destroyed.
    void tabbedView_ControlReleasing(object sender, ControlReleasingEventArgs e) {
        e.Cancel = true;
        //or
        //e.KeepControl = true;
    }
}

When you need to populate multiple similar Documents, you can specify their BaseDocument.Tag property. Then, when handling the QueryControl event, you can check these tags and depending on their values pass a required content to a current Document. The code below illustrates how to pass different detail User Controls depending on the employee department.


//assign string tags to all documents
document1.Tag = "Developer";
document2.Tag = "Support";
document3.Tag = "TechWriter";
document4.Tag = "QA";
document5.Tag = "HR";

private void tabbedView1_QueryControl(object sender, DevExpress.XtraBars.Docking2010.Views.QueryControlEventArgs e) {
    //check document tags and pick a corresponding User Control for each document
    switch (e.Document.Tag.ToString()) {
        case "Developer":
            e.Control = new developerDetailUserControl();
            break;
        case "Support":
            e.Control = new supportDetailUserControl();
            break;
        case "TechWriter":
            e.Control = new techWriterDetailUserControl();
            break;
        case "QA":
            e.Control = new QADetailUserControl();
            break;
        case "HR":
            e.Control = new HRDetailUserControl();
            break;
    }
}

Navigation through documents can be accompanied by a load indicator (see the figure below). Its availability is specified via the BaseView.UseLoadingIndicator property. You can access a loading indicator's appearance settings using the BaseView.LoadingIndicatorProperties property.

DocumentManager - LoadingIndicator

See Also