Question

I have several MDI multi-tabbed Winforms apps that I wrote, using DevExpress controls (DocumentManager and BarManager), that I am trying to add behavior such that undocking a child form (FormEditor) and dragging out of the container will create a new instance of the container (FormMaster.2) and add the child to it, so the child form is always within an MDI container. I'm trying to achieve the effect similar to tab docking in Internet Explorer, Chrome, etc.

So far, my approach has resulted in a disappearing child and a .NET Exception: Top-level style of a parented control cannot be changed

EDITED: In the original question, I noted that I tried hooking into ParentChanged event, and instantiating a new instance of my MDI Parent Form for proof of concept. That was only temporary because that event fires immediately when the child is undocked, which is too soon. I set the child.ParentChanged event to check for Parent == null, and then created a new FormMaster container and set MdiParent within the same event. It didn't work.

ANSWER: DmitryG pointed me to the DevExpress BaseView.FloatingDocumentContainer property. Setting DocumentManager.View.FloatingDocumentContainer = DocumentsHost. Using that is enough for a default solution, but you'll probably want to go a step further and override the default container with your own form. The CustomDocumentsHostWindow event allowed me to provide a constructor to instantiate my specific, custom MDI Parent form. The form has to implement IDocumentsHostWindow interface, the bare minimum of which is only two simple properties.

Thanks to DmitryG for the correct answer. I am providing my final solution code here for SO readers, per the docs here: BaseView.CustomDocumentsHostWindow Event

   // FormMain should be setup as an MDIParent with appropriate settings for tabbed MDI, etc.
   public partial class FormMain : XtraForm, IDocumentsHostWindow
   {
      public FormMain()
      {
         InitializeComponent(); 
         documentManager1.View.FloatingDocumentContainer = FloatingDocumentContainer.DocumentsHost;
         documentManager1.View.CustomDocumentsHostWindow +=
             (sender, args) => {
                 args.Constructor = () => new FormMain(); // instantiate my custom parent
             };
      }

      // interface IDocumentsHostWindow
      public bool DestroyOnRemovingChildren
      {
         get { return true; }
      }

      public DocumentManager DocumentManager
      {
         get { return documentManager1; }
      }
   }

This worked with slightly older DevExpress 12.1 as well.

Was it helpful?

Solution

As far as I know, the DevExpress DocumentManager provide the required functionality without any additional coding with using the FloatingDocumentContainer feature - if the BaseView.FloatingDocumentContainer property is set to DocumentsHost, floating documents are hosted within a container to which other documents can be docked. Documents docked to such a floating container are presented as tabs.

The BaseView.CustomDocumentsHostWindow event allows to provide your custom form as a host-window for floating documents.

P.S. You can play with this functionality using their Docking 2013 UI technical demo that replicates Visual Studio 2013 UI. (latest free trial)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top