How to dock floating pane back to where it was

6 posts, 1 answers
  1. Nikita
    Nikita avatar
    13 posts
    Member since:
    Jan 2015

    Posted 13 Feb 2015 Link to this post

    Hello.

    My scenario is pretty streight forward:
    1) User docks a Pane to arbitrary position by dragging it with a mouse.
    2) He then undocks it.
    3) He then clicks a button which is supposed to dock the pane back where it was before undocking.

    How do i impement (3) ? Is there an example somehere? How do I "store" position of single docked Pane in docking tree, and how do i "restore" it when needed?
  2. Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 16 Feb 2015 Link to this post

    Hi Nikita,

    The desired functionality could easily be accomplished by using the Save/Load layout mechanism of RadDocking. That mechanism provides the ability to store the layout of RadDocking into a XML file and load it back when needed. Please, check the following article from our help documentation and that sample project from our SDK Repository that demonstrates how to easily implement that mechanism:
    http://docs.telerik.com/devtools/wpf/controls/raddocking/features/save-load-layout.html

    Hopes this helps.

    Regards,
    Nasko
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Nikita
    Nikita avatar
    13 posts
    Member since:
    Jan 2015

    Posted 25 Feb 2015 in reply to Nasko Link to this post

    Yes, I have seen this example. I don't need to save the entire layout though. I need to save docked position of individual pane. When I restore it, only this pane should move to previously saved position. The rest of layout should remain unaffected (which is why I cannot use SaveLayout and LoadLayout methods). I found no easy way to achieve this functionality.
  5. Answer
    Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 27 Feb 2015 Link to this post

    Hi Nikita,

    I'm afraid that RadDocking control doesn't support that functionality with its current implementation. We have an item in our Feedback portal about allowing implementing custom save/load layout logic - the desired by you functionality will also be considered for implementing. You could follow the status of the item on the following link:
    http://feedback.telerik.com/Project/143/Feedback/Details/67014-allow-writing-custom-save-load-layout-logic

    Hopes this helps.

    Regards,
    Nasko
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. Nikita
    Nikita avatar
    13 posts
    Member since:
    Jan 2015

    Posted 02 Mar 2015 Link to this post

    In case someone is wondering, here is a workaround I came up with

    //viewmodel class
    public class ScreenViewModel
    {
        public RadPane Pane { get; set; }
        public IPaneContainer Container { get; set; }
     
        //this method docks floating pane back to where it was
        public void DockBack()
        {
           if (!Pane.IsFloating) return;
           if (Container == null)
           {
               Pane.MoveToDocumentHost();
           }
           else
           {
               Container.MoveToContainer(Pane);
           }
        }
    }
    //this interface represents pane container (pane group or document host)
        public interface IPaneContainer
        {
            //locks container in place by setting IsAutoGenerated to false
            //so it is not automatically removed from visual tree
           //when pane is undocked
            void Lock();
            //returns true if container contains specified pane
            bool Contains(RadPane pane);
            //docks pane to this container
            void MoveToContainer(RadPane pane);
            //releases container by setting IsAutoGenerated to true
           //if lock count goes to 0
            bool Release();
        }
     
        //implementation for autogenerated RadPaneGroup's
        class GroupContainer : IPaneContainer
        {
            public GroupContainer(RadPaneGroup group)
            {
                _group = group;
                RadDocking.SetIsAutoGenerated(group, false);
            }
     
            public void Lock()
            {
                _refCount++;
            }
     
            public bool Contains(RadPane pane)
            {
                return _group.EnumeratePanes().Any(x => x == pane);
            }
     
            public void MoveToContainer(RadPane pane)
            {
                pane.RemoveFromParent();
                _group.AddItem(pane, DockPosition.Center);
            }
     
            public bool Release()
            {
                _refCount--;
                if (_refCount == 0)
                {
                    RadDocking.SetIsAutoGenerated(_group, true);
                    return true;
                }
                return false;
            }
     
            private int _refCount;
            private readonly RadPaneGroup _group;
        }
     
    //implementation for RadPaneGroup's, declared in xaml
    //those should always have IsAutoGenerated set to false
        class NamedGroupContainer : IPaneContainer
        {
            private readonly RadPaneGroup _group;
     
            public NamedGroupContainer(RadPaneGroup group)
            {
                _group = group;
            }
     
            public void Lock()
            {
            }
     
            public bool Contains(RadPane pane)
            {
                return _group.EnumeratePanes().Any(x => x == pane);
            }
     
            public void MoveToContainer(RadPane pane)
            {
                pane.RemoveFromParent();
                _group.AddItem(pane, DockPosition.Center);
            }
     
            public bool Release()
            {
                return false;
            }
        }
     
    //implementation for DocumentHost
        class DocumentContainer : IPaneContainer
        {
            public void Lock()
            {
            }
     
            public bool Contains(RadPane pane)
            {
                return pane.IsInDocumentHost;
            }
     
            public void MoveToContainer(RadPane pane)
            {
                pane.MoveToDocumentHost();
            }
     
            public bool Release()
            {
                return false;
            }
        }
     
    //factory for IPaneContainer's
        static class PaneContainerFactory
        {
            public static IPaneContainer Create(RadPane pane)
            {
                if (pane.IsInDocumentHost)
                {
                    return new DocumentContainer();
                }
     
                if (!String.IsNullOrEmpty(pane.PaneGroup.Name))
                {
                    return new NamedGroupContainer(pane.PaneGroup);
                }
     
                return new GroupContainer(pane.PaneGroup);
            }
        }
     
    //RadDocking.PaneStateChange event handler
            private void OnPaneStateChanged(object sender, RadRoutedEventArgs e)
            {
                var pane = (RadPane) e.OriginalSource;
                var vm = Screens.First(x => x.Pane == pane);
                if (!pane.IsFloating)
                {
                   //release previous container
                    if (vm.Container != null)
                    {
                        if (vm.Container.Release())
                        {
                            _containers.Remove(vm.Container);
                        }
                    }
     
                  //lock new container
                    var container = _containers.FirstOrDefault(x => x.Contains(pane));
                    if (container == null)
                    {
                        container = PaneContainerFactory.Create(pane);
                        _containers.Add(container);
                    }
                     container.Lock();
                    vm.Container = container;
                }
            }
     
            private readonly IList<IPaneContainer> _containers = new List<IPaneContainer>();
            public ObservableCollection<ScreenViewModel> Screens { get; set; }

    It works so far, but it would be really nice to have an inbuilt functionality for that stuff. I mean, reference counting just to dock pane back? Come on :)
  7. Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 04 Mar 2015 Link to this post

    Hello Nikita,

    Thank you for sharing your solution with us. You could also continue following the status of the item from my previous response in order to be aware of any changes made on it.

    Do not hesitate to contact us if you have any additional questions or concerns regarding Telerik controls.

    Regards,
    Nasko
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready