Problem with DocumentInsertOrder

12 posts, 1 answers
  1. Roman
    Roman avatar
    5 posts
    Member since:
    Aug 2010

    Posted 02 Oct 2010 Link to this post

    Hello!

    We have a window with many documents. Each document puts to the end of the opened documents:

    radDock.DocumentManager.DocumentInsertOrder =

     

    DockWindowInsertOrder.ToBack;

     

     


    Usually it's working, but when we have no more place for a new tab, the document puts in front of the opened documents. But we always expect to see it as a last document, not first! 

    Pic.png demonstrates unexpected behavior (fist tab must be Window#1, not Window#3). This problem is reproducing in WinForms docking, ver. 2010.2.10.806
  2. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 04 Oct 2010 Link to this post

    Hi Roman, 

    As far as I'm aware this is expected behaviour. If you add Documents to the RadDock, with the DocumentInsertOrder set ToBack, then it will continue to add documents to the right most position and to the back. Once it has run out of space it will continue to add documents to the back, right most position. But, when you select one of those documents that are out of view on the right side, then it will place the document tab on the left most position. 
    RIchard
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 05 Oct 2010 Link to this post

    Hello Roman,

    Please try the following example:
    using Telerik.WinControls.UI;
        using Telerik.WinControls.UI.Docking;
     
        public partial class Form1 : Form
        {
            private RadDock radDock1 = new RadDock();
     
            public Form1()
            {
                InitializeComponent();
                this.Load += new System.EventHandler(Form1_Load);
            }
     
            void Form1_Load(object sender, System.EventArgs e)
            {
                radDock1.Dock = DockStyle.Fill;
                radDock1.DocumentManager.DocumentInsertOrder = DockWindowInsertOrder.ToBack;
                this.Controls.Add(radDock1);
     
                var addWindowButton = new RadButton();
                addWindowButton.Text = "Add window to the back...";
                addWindowButton.Click += new System.EventHandler(addWindowButton_Click);
                addWindowButton.Dock = DockStyle.Bottom;
                this.Controls.Add(addWindowButton);
            }
     
            void addWindowButton_Click(object sender, System.EventArgs e)
            {
                DocumentWindow documentTop = new DocumentWindow();
                documentTop.Text = radDock1.DockWindows.Count.ToString();
                this.radDock1.AddDocument(documentTop);
            }
        }

    I am using version Q2 2010 SP2 of the telerik controls, if this example is not working as expected please try updating to the latest version,

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga
  5. Roman
    Roman avatar
    5 posts
    Member since:
    Aug 2010

    Posted 06 Oct 2010 Link to this post

    Hello, Emanuel,

    Thank you for this solution, may be, it will be useful in our project.
    I have only one more question: do we have any way to make the first window "always on top"? Really, I only need to fix the first window, and it's no difference about placing other hundreds of opened documents :)

    Roman
  6. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 06 Oct 2010 Link to this post

    Hello Roman,

    What do you mean by always on top?

    Best Regards,
    Emanuel Varga
  7. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 06 Oct 2010 Link to this post

    Hi, 

    If I can contribute here, when you ask a document window to be on top, it always does place the new one on top. I believe that Roman's issue is that once the RadDock is full of documents, then the next window to open places the document at the start of all the tabs again. 

    So, if a RadDock has space for 5 documents (visually) then it will place them as 
    0,1,2,3,4
    When you open document 5 it places it as 
    5,0,1,2,3

    It is my understanding that this is expected behaviour. 
    Richard
  8. Roman
    Roman avatar
    5 posts
    Member since:
    Aug 2010

    Posted 06 Oct 2010 Link to this post

    Hello, Emmanuel,

    Richard already answered ;)
    Yes, Richard, I know, that it's usual behavior, we can see it in VisualStudio for example :)
    I need window 0 to be always first, so, after "0, 1, 2, 3, 4", and when I open fifth, I want to see windows in the next order "0, 5, 1, 2, 3". Before we start using Telerik controls, we used Krypton Toolkit, and tabs only changed their size, but didn't change place. In our project first window was always opened, and it's a "Main window", all users always expect it to be on top (i.e. first).
  9. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 06 Oct 2010 Link to this post

    Hello Richard,

    Help and opinions are always appreciated, just hope you don't mind me interfering :).

    But didn't he say that he wants the windows to appear in the order that they were created, no?
    So 0,1,2,3,4,5, or not?

    If you want to change this behavior in a specific case you could always just do something like this:
    using System.Drawing;
        using System.Windows.Forms;
        using Telerik.WinControls.UI;
        using Telerik.WinControls.UI.Docking;
     
        public partial class Form1 : Form
        {
            private RadDock radDock1 = new RadDock();
     
            public Form1()
            {
                InitializeComponent();
                this.Load += new System.EventHandler(Form1_Load);
                this.Size = new Size(500, 400);
            }
     
            void Form1_Load(object sender, System.EventArgs e)
            {
                radDock1.Dock = DockStyle.Fill;
                radDock1.DocumentManager.DocumentInsertOrder = DockWindowInsertOrder.ToBack;
                this.Controls.Add(radDock1);
     
                var addWindowButton = new RadButton();
                addWindowButton.Text = "Add window according the DocumentInsertOrder...";
                addWindowButton.Click += new System.EventHandler(addWindowButton_Click);
                addWindowButton.Dock = DockStyle.Bottom;
                this.Controls.Add(addWindowButton);
     
                var addWindowFrontButton = new RadButton();
                addWindowFrontButton.Text = "Add window to the front...";
                addWindowFrontButton.Click += new System.EventHandler(addWindowFrontButton_Click);
                addWindowFrontButton.Dock = DockStyle.Bottom;
                this.Controls.Add(addWindowFrontButton);
            }
     
            void addWindowFrontButton_Click(object sender, System.EventArgs e)
            {
                var insertOrder = radDock1.DocumentManager.DocumentInsertOrder;
                DocumentWindow documentTop = new DocumentWindow();
                documentTop.Text = radDock1.DockWindows.Count.ToString();
     
                if (insertOrder != DockWindowInsertOrder.InFront)
                {
                    radDock1.DocumentManager.DocumentInsertOrder = DockWindowInsertOrder.InFront;
                }
     
                this.radDock1.AddDocument(documentTop);
                radDock1.DocumentManager.DocumentInsertOrder = insertOrder;
            }
     
            void addWindowButton_Click(object sender, System.EventArgs e)
            {
                DocumentWindow documentTop = new DocumentWindow();
                documentTop.Text = radDock1.DockWindows.Count.ToString();
                this.radDock1.AddDocument(documentTop);
            }
        }

    Like this, if the current order is different when you want to perform an insert InFront, you just keep the old value, change the insert order, and insert the image, and after that change the value back.

    Or, there is a different way of doing things, you can register to the DockWindowAdded event and you can easily add your own custom behavior by changing the index of the document. Something like this:
    private void radDock1_DockWindowAdded(object sender, DockWindowEventArgs e) 
        if (e.DockWindow is DocumentWindow) 
        
            DockTabStrip strip = e.DockWindow.DockTabStrip; 
            if (strip != null
            
                strip.Controls.SetChildIndex(e.DockWindow, strip.Controls.Count - 1); 
            
        
    }

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga
  10. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 06 Oct 2010 Link to this post

    Hello again guys,

    Sorry for the late answer and wrong one because i didn't refresh the page,

    to have the desired behavior you can change the DockWindowAdded like this:
    private void radDock1_DockWindowAdded(object sender, DockWindowEventArgs e)
    {
        if (e.DockWindow is DocumentWindow)
        {
            DockTabStrip strip = e.DockWindow.DockTabStrip;
            if (strip != null)
            {
                e.DockWindow.EnsureVisible();
     
                if (strip.Controls.Count > 2 && strip.Controls[0] == e.DockWindow)
                {
                    strip.Controls.SetChildIndex(strip.Controls[1], 0);
                    strip.Controls.SetChildIndex(e.DockWindow, 1);
                }
                else
                {
                    strip.Controls.SetChildIndex(e.DockWindow, strip.Controls.Count - 1);
                }
            }
        }
    }

    This will do what you want, in my opinion this can be extended to support pinned items, it can be done very easily like this, just keep a list of pinned items, make sure those items are the first items, and whenever you create a new item, (when there is not enough space for it) add it after the pinned items.

    Best Regards,
    Emanuel Varga
  11. Roman
    Roman avatar
    5 posts
    Member since:
    Aug 2010

    Posted 06 Oct 2010 Link to this post

    I think, it's all I need :)
    Thank you very much, guys!

    With best regards,
    Roman.
  12. Answer
    Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 06 Oct 2010 Link to this post

    Hello again guys,

    When i got the idea to create a pin for documents had to try it, here is the code if someone could use it:

    using System.Drawing;
       using System.Windows.Forms;
       using Telerik.WinControls.UI;
       using Telerik.WinControls.UI.Docking;
     
       public partial class Form1 : Form
       {
           private RadDock radDock1 = new RadDock();
     
           public Form1()
           {
               InitializeComponent();
               this.Load += new System.EventHandler(Form1_Load);
               this.Size = new Size(500, 400);
           }
     
           void Form1_Load(object sender, System.EventArgs e)
           {
               radDock1.Dock = DockStyle.Fill;
               radDock1.DocumentManager.DocumentInsertOrder = DockWindowInsertOrder.ToBack;
               this.Controls.Add(radDock1);
     
               ContextMenuService menuService = this.radDock1.GetService<ContextMenuService>();
               menuService.ContextMenuDisplaying += menuService_ContextMenuDisplaying;
     
               radDock1.DockWindowAdded += new DockWindowEventHandler(radDock1_DockWindowAdded);
     
               var addWindowButton = new RadButton();
               addWindowButton.Text = "Add window according the DocumentInsertOrder...";
               addWindowButton.Click += new System.EventHandler(addWindowButton_Click);
               addWindowButton.Dock = DockStyle.Bottom;
               this.Controls.Add(addWindowButton);
           }
     
           private void menuService_ContextMenuDisplaying(object sender, ContextMenuDisplayingEventArgs e)
           {
               if (e.MenuType == ContextMenuType.DockWindow &&
                   e.DockWindow.DockTabStrip is DocumentTabStrip)
               {
                   var pinnableWindow = (PinnableDocumentWindow)e.DockWindow;
     
                   RadMenuItem pinItem = new RadMenuItem(!pinnableWindow.IsPinned ? "Pin It!" : "Unpin It!");
                   pinItem.Tag = e.DockWindow;
                   pinItem.Click += new System.EventHandler(pinItem_Click);
                   e.MenuItems.Insert(0, pinItem);
               }
           }
     
           void pinItem_Click(object sender, System.EventArgs e)
           {
               var dockWindow = (PinnableDocumentWindow)((RadMenuItem)sender).Tag;
               dockWindow.IsPinned = !dockWindow.IsPinned;
               dockWindow.Image = dockWindow.IsPinned ? Properties.Resources.pin14 : null;
     
               MoveTabToNewPosition(dockWindow);
           }
     
           private void radDock1_DockWindowAdded(object sender, DockWindowEventArgs e)
           {
               if (e.DockWindow is DocumentWindow)
               {
                   MoveTabToNewPosition(e.DockWindow);
               }
           }
     
           private static void MoveTabToNewPosition(DockWindow dockWindow)
           {
               dockWindow.EnsureVisible();
               var currentPinnableWindow = (PinnableDocumentWindow)dockWindow;
               var strip = dockWindow.DockTabStrip;
     
               if (strip == null)
               {
                   return;
               }
     
               if (strip.Controls.Count > 2 && strip.Controls[0] == dockWindow || currentPinnableWindow.IsPinned)
               {
                   var index = 0;
                   for (int i = 0; i < strip.Controls.Count; i++)
                   {
                       var pinnableWindow = (PinnableDocumentWindow)strip.Controls[i];
                       if (pinnableWindow == dockWindow)
                       {
                           continue;
                       }
     
                       if (!pinnableWindow.IsPinned)
                       {
                           break;
                       }
     
                       index++;
                   }
     
                   strip.Controls.SetChildIndex(dockWindow, index);
               }
               else
               {
                   strip.Controls.SetChildIndex(dockWindow, strip.Controls.Count - 1);
               }
           }
     
           void addWindowButton_Click(object sender, System.EventArgs e)
           {
               PinnableDocumentWindow documentTop = new PinnableDocumentWindow();
               documentTop.Text = radDock1.DockWindows.Count.ToString();
               this.radDock1.AddDocument(documentTop);
           }
       }
     
       public class PinnableDocumentWindow : DocumentWindow
       {
           private bool isPinned = false;
     
           public bool IsPinned
           {
               get
               {
                   return isPinned;
               }
               set
               {
                   isPinned = value;
               }
           }
       }

    It's using the context menu for the document to toggle the pin state, and it's moving all the windows based on these values.

    *update i forgot to mention that i have attached an image of the app, and the image for the pin

    Best Regards,
    Emanuel Varga
  13. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 06 Oct 2010 Link to this post

    Emanuel, 
    That's pretty cool. Perhaps it should be submitted to the Code Library. 
    Richard
Back to Top
UI for WinForms is Visual Studio 2017 Ready