Exemplo n.º 1
0
 internal void AddDockControl(IDockControl ctrl)
 {
     if (!_dockControls.ContainsKey(ctrl.ID))
     {
         _dockControls.Add(ctrl.ID, ctrl);
     }
 }
Exemplo n.º 2
0
 internal void RemoveDockControl(IDockControl ctrl)
 {
     if (_dockControls.ContainsKey(ctrl.ID))
     {
         _dockControls.Remove(ctrl.ID);
     }
 }
Exemplo n.º 3
0
        private void RegisterEventHandlers(IDockControl dataContext)
        {
            if (dataContext == null)
            {
                return;
            }

            // Attach to IDockControl.
            if (dataContext.DockStrategy == null)
            {
                throw new DockException("IDockControl.DockStrategy must not be null.");
            }

            DockStrategy = dataContext.DockStrategy;

            // Observe IDockControl properties.
            PropertyChangedEventManager.AddHandler(dataContext, OnDockStrategyChanged, nameof(IDockControl.DockStrategy));
            PropertyChangedEventManager.AddHandler(dataContext, OnActiveItemChanged, nameof(IDockControl.ActiveDockTabItem));
            //PropertyChangedEventManager.AddHandler(dataContext, OnActivePaneChanged, nameof(IDockControl.ActiveDockTabPane));

            // The ICollectionView is used to filter IFloatWindows.
            var collectionView            = CollectionViewSource.GetDefaultView(dataContext.FloatWindows);
            var collectionViewLiveShaping = collectionView as ICollectionViewLiveShaping;

            if (collectionViewLiveShaping != null && collectionViewLiveShaping.CanChangeLiveFiltering)
            {
                collectionViewLiveShaping.LiveFilteringProperties.Clear();
                collectionViewLiveShaping.LiveFilteringProperties.Add(nameof(IFloatWindow.IsVisible));
                collectionViewLiveShaping.IsLiveFiltering = true;
                collectionView.Filter = floatWindow => ((IFloatWindow)floatWindow).IsVisible;
            }
            CollectionChangedEventManager.AddHandler(collectionView, OnFloatWindowsChanged);
        }
Exemplo n.º 4
0
        public WorldView(DockManager dockManager, IDockControl navigateDockControl, Action <Scross> setScross, EditMode editMode)
        {
            _setScross          = setScross;
            _editMode           = editMode;
            _dockManager        = dockManager;
            NavigateDockControl = navigateDockControl;

            InitializeComponent();

            DataContext = this;
        }
Exemplo n.º 5
0
 internal void AddDockControl(IDockControl ctrl)
 {
     if (!_dockControls.ContainsKey(ctrl.ID))
     {
         _dockControls.Add(ctrl.ID, ctrl);
     }
     else
     {
         throw new InvalidOperationException(string.Format("id {0} is repeated!", ctrl.ID));
     }
 }
Exemplo n.º 6
0
        internal void RemoveDockControl(IDockControl ctrl)
        {
            if (_dockControls.ContainsKey(ctrl.ID))
            {
                _dockControls.Remove(ctrl.ID);

                if (ctrl.ID >= _fixCount)
                {
                    _disposedID.Push(ctrl.ID);
                }
            }
        }
Exemplo n.º 7
0
            public SerializationContext(IDockControl dockControl)
            {
                Debug.Assert(dockControl != null);
                Debug.Assert(dockControl.DockStrategy != null);

                DockControl = dockControl;

                var dockStrategy = dockControl.DockStrategy;

                DefaultFloatWindow    = dockStrategy.CreateFloatWindow();
                DefaultDockAnchorPane = dockStrategy.CreateDockAnchorPane();
                DefaultDockSplitPane  = dockStrategy.CreateDockSplitPane();
                DefaultDockTabPane    = dockStrategy.CreateDockTabPane();
            }
Exemplo n.º 8
0
        public IDockControl ApplyLayout(DockManager dockManager, IDockControl target, Direction dir)
        {
            var relative = default(IDockControl);

            foreach (var child in _children)
            {
                var ele = dockManager.GetDockControl(child.ID);
                dockManager.AttachTo(ele, target, dir == Direction.Horizontal ? AttachMode.Right : AttachMode.Bottom);
                if (relative == null)
                {
                    relative = ele;
                }
            }
            return(relative);
        }
Exemplo n.º 9
0
 public IDockControl TryGetFirstLevelElement(DockManager dockManager, IDockControl target = null, Direction dir = Direction.None, bool isFloat = false)
 {
     if (_children.First.Value.Type == LayoutNodeType.Panel)
     {
         return((_children.First.Value as PanelNode).TryGetFirstLevelElement(dockManager, target, dir, isFloat));
     }
     else if (target != null)
     {
         return((_children.First.Value as GroupNode).ApplyLayout(dockManager, target, dir));
     }
     else
     {
         return((_children.First.Value as GroupNode).ApplyLayout(dockManager, isFloat));
     }
 }
Exemplo n.º 10
0
 /// <summary>
 /// attach source to target by <see cref="AttachMode"/>
 /// </summary>
 /// <param name="source">源</param>
 /// <param name="target">目标</param>
 /// <param name="mode">附加模式</param>
 public void AttachTo(IDockControl source, IDockControl target, AttachMode mode)
 {
     if (target.Container.View == null)
     {
         throw new InvalidOperationException("target must be visible!");
     }
     if (target.IsDisposed)
     {
         throw new InvalidOperationException("target is disposed!");
     }
     if (source == target)
     {
         throw new InvalidOperationException("source can not be target!");
     }
     if (source == null || target == null)
     {
         throw new ArgumentNullException("source or target is null!");
     }
     if (source.Container.View != target.Container.View && source.CanSelect)
     {
         source.SetActive();
     }
     else if (source.Container != null)
     {
         source.Container.Detach(source.ProtoType);
         BaseLayoutGroup  group;
         BaseGroupControl ctrl;
         if (source.IsDocument)
         {
             group = new LayoutDocumentGroup(DockMode.Normal, this);
             ctrl  = new LayoutDocumentGroupControl(group, (target.Container.View as ILayoutViewWithSize).DesiredWidth, (target.Container.View as ILayoutViewWithSize).DesiredHeight);
         }
         else
         {
             group = new LayoutGroup(source.Side, DockMode.Normal, this);
             ctrl  = new AnchorSideGroupControl(group, (target.Container.View as ILayoutViewWithSize).DesiredWidth, (target.Container.View as ILayoutViewWithSize).DesiredHeight);
         }
         group.Attach(source.ProtoType);
         var _atsource = target.ProtoType.Container.View as IAttcah;
         _atsource.AttachWith(ctrl, mode);
         source.SetActive();
     }
     else
     {
         throw new ArgumentNullException("the container of source is null!");
     }
 }
Exemplo n.º 11
0
        private void UnregisterEventHandlers(IDockControl dataContext)
        {
            if (dataContext == null)
            {
                return;
            }

            // Detach from IDockControl.
            DockStrategy = null;
            PropertyChangedEventManager.RemoveHandler(dataContext, OnDockStrategyChanged, nameof(IDockControl.DockStrategy));
            PropertyChangedEventManager.RemoveHandler(dataContext, OnActiveItemChanged, nameof(IDockControl.ActiveDockTabItem));
            //PropertyChangedEventManager.RemoveHandler(dataContext, OnActivePaneChanged, nameof(IDockControl.ActiveDockTabPane));

            var collectionView = CollectionViewSource.GetDefaultView(dataContext.FloatWindows);

            CollectionChangedEventManager.RemoveHandler(collectionView, OnFloatWindowsChanged);
        }
Exemplo n.º 12
0
        public int GetDocumentTabIndex(IDockControl dockControl)
        {
            int index = -1;

            foreach (var model in _root.DocumentModels)
            {
                index++;
                foreach (var item in model.Children)
                {
                    if (item == dockControl.ProtoType)
                    {
                        return(index);
                    }
                }
            }

            return(-1);
        }
Exemplo n.º 13
0
        private void _TryCompleteLayout(DockManager dockManager, IDockControl relative, bool isFloat = false)
        {
            var dic      = new Dictionary <IDockControl, PanelNode>();
            var children = relative == null ? _children : _children.Skip(1);

            if (relative != null && _children.First.Value.Type == LayoutNodeType.Panel)
            {
                dic.Add(relative, _children.First.Value as PanelNode);
            }

            foreach (var item in children)
            {
                if (relative == null)
                {
                    if (item.Type == LayoutNodeType.Group)
                    {
                        relative = (item as GroupNode).ApplyLayout(dockManager, isFloat);
                    }
                    else
                    {
                        relative = (item as PanelNode).TryGetFirstLevelElement(dockManager, null, Direction.None, isFloat);
                        dic.Add(relative, item as PanelNode);
                    }
                }
                else
                {
                    if (item.Type == LayoutNodeType.Group)
                    {
                        relative = (item as GroupNode).ApplyLayout(dockManager, relative, _direction);
                    }
                    else
                    {
                        relative = (item as PanelNode).TryGetFirstLevelElement(dockManager, relative, _direction);
                        dic.Add(relative, item as PanelNode);
                    }
                }
            }

            foreach (var pair in dic)
            {
                pair.Value._TryCompleteLayout(dockManager, pair.Key, isFloat);
            }
        }
Exemplo n.º 14
0
        /// <overloads>
        /// <summary>
        /// Gets all elements of the docking layout. (May include duplicates!)
        /// </summary>
        /// </overloads>
        ///
        /// <summary>
        /// Gets all elements of the <see cref="IDockControl"/>. (May include duplicates!)
        /// </summary>
        /// <param name="dockControl">The <see cref="IDockControl"/>.</param>
        /// <returns>All <see cref="IDockElement"/>s. May include duplicates!</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="dockControl"/> is <see langword="null"/>.
        /// </exception>
        public static IEnumerable <IDockElement> GetDockElements(this IDockControl dockControl)
        {
            if (dockControl == null)
            {
                throw new ArgumentNullException(nameof(dockControl));
            }

            var dockElements           = GetDockElements(dockControl.RootPane);
            var floatElements          = dockControl.FloatWindows.SelectMany(floatWindow => GetDockElements(floatWindow.RootPane));
            var autoHideLeftElements   = GetDockElements(dockControl.AutoHideLeft);
            var autoHideTopElements    = GetDockElements(dockControl.AutoHideTop);
            var autoHideRightElements  = GetDockElements(dockControl.AutoHideRight);
            var autoHideBottomElements = GetDockElements(dockControl.AutoHideBottom);

            return(dockElements.Concat(floatElements)
                   .Concat(autoHideLeftElements)
                   .Concat(autoHideTopElements)
                   .Concat(autoHideRightElements)
                   .Concat(autoHideBottomElements));
        }
Exemplo n.º 15
0
        /// <overloads>
        /// <summary>
        /// Gets the <see cref="IDockPane"/> which is the direct parent of the specified child
        /// element.
        /// </summary>
        /// </overloads>
        ///
        /// <summary>
        /// Gets the <see cref="IDockPane"/> which is the direct parent of the specified child
        /// element.
        /// </summary>
        /// <param name="dockControl">The <see cref="IDockControl"/>.</param>
        /// <param name="child">The child element.</param>
        /// <returns>
        /// The <see cref="IDockPane"/> which contains <paramref name="child"/> in its immediate
        /// children.
        /// </returns>
        public static IDockPane GetParent(IDockControl dockControl, IDockElement child)
        {
            if (dockControl == null)
            {
                throw new ArgumentNullException(nameof(dockControl));
            }
            if (child == null)
            {
                throw new ArgumentNullException(nameof(child));
            }

            Debug.Assert(child != null);
            Debug.Assert(child.DockState != DockState.Hide);

            switch (child.DockState)
            {
            case DockState.Dock:
                return(GetParent(dockControl.RootPane, child));

            case DockState.Float:
                foreach (var floatWindow in dockControl.FloatWindows)
                {
                    var dockPane = GetParent(floatWindow.RootPane, child);
                    if (dockPane != null)
                    {
                        return(dockPane);
                    }
                }
                break;

            case DockState.AutoHide:
                return(GetParent(dockControl.AutoHideLeft, child)
                       ?? GetParent(dockControl.AutoHideRight, child)
                       ?? GetParent(dockControl.AutoHideTop, child)
                       ?? GetParent(dockControl.AutoHideBottom, child));
            }

            return(null);
        }
Exemplo n.º 16
0
        public IDockControl TryApplyLayoutAsDocument(DockManager dockManager, IDockControl target)
        {
            var relative = default(IDockControl);

            foreach (var child in _children)
            {
                var ele = dockManager.GetDockControl(child.ID);
                if (ele != null)
                {
                    if (relative == null)
                    {
                        dockManager.AttachTo(ele, target, _parent.Direction == Direction.Horizontal ? AttachMode.Right_WithSplit : AttachMode.Bottom_WithSplit);
                        relative = ele;
                    }
                    else
                    {
                        dockManager.AttachTo(ele, relative, AttachMode.Center);
                    }
                }
            }
            return(relative);
        }
Exemplo n.º 17
0
        public static void Load(IDockControl dockControl, XElement storedLayout /*, bool keepDockTabItems */)
        {
            ///// <param name="keepDockTabItems">
            ///// If set to <see langword="true"/> all existing <see cref="IDockTabItem"/>s are kept. If
            ///// set to <see langword="false"/>, all current <see cref="IDockTabItem"/>s are closed
            ///// before the new layout is loaded.
            ///// </param>

            if (dockControl == null)
                throw new ArgumentNullException(nameof(dockControl));
            if (storedLayout == null)
                throw new ArgumentNullException(nameof(storedLayout));

            var dockStrategy = dockControl.DockStrategy;
            if (dockStrategy == null)
                throw new ArgumentException("The IDockControl does not have a DockStrategy.");

            const bool keepNonPersistentItems = true;  // Non-persistent items are usually documents and should be kept.
            const bool keepPersistentItems = false;    // Persistent items are usually tool windows.

            // Remember current dock items (visible and hidden items).
            var items = dockControl.GetDockElements()
                                   .OfType<IDockTabItem>()
                                   .Distinct()
                                   .ToArray();

            // Validate DockIds.
            foreach (var item in items)
                if (item.DockId == null)
                    throw new DockException("Could not load docking layout. IDockTabItem does not have a valid DockId.");

            // Check for duplicate DockIds.
            bool duplicateDockIds = items.GroupBy(item => item.DockId)
                                         .Select(group => group.Count())
                                         .Any(count => count > 1);
            if (duplicateDockIds)
                throw new DockException("Could not load docking layout. Two or more IDockTabItems have the same DockId.");

            var context = new DeserializationContext { DockControl = dockControl };

            dockStrategy.Begin();
            try
            {
                // Remember current IDockTabItems.
                // context.OldItems stores all (because OldItems is used in LoadDockTabItem).
                // Another list stores only the old items which are visible.
                var oldVisibleItems = new List<IDockTabItem>();
                foreach (var item in items)
                {
                    context.OldItems[item.DockId] = item;

                    if (item.DockState != DockState.Hide)
                        oldVisibleItems.Add(item);
                }

                // Load IDockTabItems. Do not add to the dock control yet.
                foreach (var itemXElement in storedLayout.Elements("DockTabItems").Elements())
                {
                    var item = LoadDockTabItem(context, itemXElement, onlyReference: false);
                    if (item != null)
                        context.NewItems[item.DockId] = item;
                }

                // Try to close all IDockTabItems which we will not keep or which will be hidden.
                // We keep a list of items which we need to keep open.
                var oldItemsToShow = new List<IDockTabItem>();
                foreach (var oldDockTabItem in oldVisibleItems)
                {
                    if (context.NewItems.ContainsKey(oldDockTabItem.DockId)
                        && oldDockTabItem.DockState != DockState.Hide)
                    {
                        // Item remains in the layout and visible.
                        continue;
                    }

                    // Previously visible item is removed from layout or hidden. 
                    // Try to close it. Items that cannot be closed will be shown at the end.
                    bool closed = false;
                    if ((oldDockTabItem.IsPersistent && !keepPersistentItems)
                        || (!oldDockTabItem.IsPersistent && !keepNonPersistentItems))
                    {
                        if (dockStrategy.CanClose(oldDockTabItem))
                        {
                            // Successfully closed.
                            dockStrategy.Close(oldDockTabItem);
                            closed = true;
                        }
                    }

                    if (!closed)
                        oldItemsToShow.Add(oldDockTabItem);
                }

                // The DockControl still contains the old layout with the previous IDockPane
                // view model. The old view models are still attached to the DockControl and
                // react to changes, which may cause the wrong screen conduction.
                // --> Detach IDockTabItems from old layout.
                foreach (var item in items)
                    DockHelper.Remove(dockControl, item);

                dockControl.FloatWindows.Clear();
                dockControl.AutoHideLeft.Clear();
                dockControl.AutoHideRight.Clear();
                dockControl.AutoHideTop.Clear();
                dockControl.AutoHideBottom.Clear();

                var isLocked = (bool?)context.Checked(storedLayout.Attribute("IsLocked"));
                if (isLocked != null)
                    dockControl.IsLocked = isLocked.Value;

                // Load float windows.
                {
                    foreach (var xElement in storedLayout.Elements("FloatWindows").Elements())
                    {
                        var floatWindow = LoadFloatWindow(context, xElement);
                        if (floatWindow != null)
                            dockControl.FloatWindows.Add(floatWindow);
                    }
                }

                // Load auto-hide panes.
                {
                    var autoHideBars = new[]
                    {
                        new { Bar = dockControl.AutoHideLeft, Name = "AutoHideLeft" },
                        new { Bar = dockControl.AutoHideRight, Name = "AutoHideRight" },
                        new { Bar = dockControl.AutoHideTop, Name = "AutoHideTop" },
                        new { Bar = dockControl.AutoHideBottom, Name = "AutoHideBottom" },
                    };

                    foreach (var bar in autoHideBars)
                    {
                        foreach (var xElement in storedLayout.Elements(bar.Name).Elements())
                        {
                            var dockPane = LoadDockPane(context, xElement);
                            if (dockPane != null)
                                bar.Bar.Add((IDockTabPane)dockPane);
                        }
                    }
                }

                // Load root pane. (We do this after loading the float windows and auto-hide bars,
                // because the dock strategy might want to activate an item in a float window or
                // auto-hide bar).
                dockControl.RootPane = LoadDockPane(context, storedLayout.Elements("RootPane").Elements().FirstOrDefault());

                // Run cleanup to update IsVisible flags. Those should be up-to-date before calling
                // Show() to find good default dock target positions.
                dockStrategy.Cleanup();

                // This is not done in cleanup if we are inside Begin()/End().
                dockControl.ActiveDockTabPane = null;
                dockControl.ActiveDockTabItem = null;

                // Show all old items that are not visible in the loaded layout but could not be closed.
                foreach (var item in oldItemsToShow)
                    dockStrategy.Show(item);

                // Activate item.
                if (context.ActiveItem != null)
                    dockStrategy.Show(context.ActiveItem);

                context.ResetLineInfo();
            }
            catch (Exception exception)
            {
                var message = "Could not load docking layout.";

                if (context.LineInfo != null && context.LineInfo.HasLineInfo())
                    message += Invariant($" Error at line {context.LineInfo.LineNumber}, column {context.LineInfo.LinePosition}.");

                message += " See inner exception for more details.";

                throw new DockException(message, exception);
            }
            finally
            {
                dockStrategy.End();
            }
        }
Exemplo n.º 18
0
            public SerializationContext(IDockControl dockControl)
            {
                Debug.Assert(dockControl != null);
                Debug.Assert(dockControl.DockStrategy != null);

                DockControl = dockControl;

                var dockStrategy = dockControl.DockStrategy;
                DefaultFloatWindow = dockStrategy.CreateFloatWindow();
                DefaultDockAnchorPane = dockStrategy.CreateDockAnchorPane();
                DefaultDockSplitPane = dockStrategy.CreateDockSplitPane();
                DefaultDockTabPane = dockStrategy.CreateDockTabPane();
            }
Exemplo n.º 19
0
        /// <summary>
        /// attach source to target by <see cref="AttachMode"/>
        /// </summary>
        /// <param name="source">源</param>
        /// <param name="target">目标</param>
        /// <param name="mode">附加模式</param>
        public void AttachTo(IDockControl source, IDockControl target, AttachMode mode, double ratio = -1)
        {
            if (target.Container.View == null)
            {
                throw new InvalidOperationException("target must be visible!");
            }
            if (target.IsDisposed)
            {
                throw new InvalidOperationException("target is disposed!");
            }
            if (source == target)
            {
                throw new InvalidOperationException("source can not be target!");
            }
            if (source == null || target == null)
            {
                throw new ArgumentNullException("source or target is null!");
            }
            if (target.Mode == DockMode.DockBar)
            {
                throw new ArgumentNullException("target is DockBar Mode!");
            }
            if (source.Container != null)
            {
                //DockBar模式下无法合并,故先转换为Normal模式
                //if (target.Mode == DockMode.DockBar)
                //    target.ToDock();

                source.Container.Detach(source.ProtoType);


                double width = (target.Container.View as ILayoutViewWithSize).DesiredWidth
                , height     = (target.Container.View as ILayoutViewWithSize).DesiredHeight;

                if (ratio > 0)
                {
                    if (mode == AttachMode.Right ||
                        mode == AttachMode.Left ||
                        mode == AttachMode.Left_WithSplit ||
                        mode == AttachMode.Right_WithSplit)
                    {
                        width = (target.Container.View as ILayoutViewWithSize).DesiredWidth * ratio;
                    }

                    if (mode == AttachMode.Top ||
                        mode == AttachMode.Bottom ||
                        mode == AttachMode.Top_WithSplit ||
                        mode == AttachMode.Bottom_WithSplit)
                    {
                        height = (target.Container.View as ILayoutViewWithSize).DesiredHeight * ratio;
                    }
                }

                BaseLayoutGroup  group;
                BaseGroupControl ctrl;
                if (source.IsDocument)
                {
                    group = new LayoutDocumentGroup(DockMode.Normal, this);
                    ctrl  = new LayoutDocumentGroupControl(group, ratio > 0 ? width : source.DesiredWidth, ratio > 0 ? height : source.DesiredHeight);
                }
                else
                {
                    group = new LayoutGroup(source.Side, DockMode.Normal, this);
                    ctrl  = new AnchorSideGroupControl(group, ratio > 0 ? width : source.DesiredWidth, ratio > 0 ? height : source.DesiredHeight);
                }
                group.Attach(source.ProtoType);
                var _atsource = target.ProtoType.Container.View as IAttcah;
                _atsource.AttachWith(ctrl, mode);
                source.SetActive();
            }
            else
            {
                throw new ArgumentNullException("the container of source is null!");
            }
        }
Exemplo n.º 20
0
 public static XElement Save(IDockControl dockControl)
 {
     return Save(dockControl, false);
 }
Exemplo n.º 21
0
        public static XElement Save(IDockControl dockControl, bool excludeNonPersistentItems)
        {
            if (dockControl == null)
                throw new ArgumentNullException(nameof(dockControl));
            if (dockControl.DockStrategy == null)
                throw new ArgumentException("The dock control does not have a dock strategy.");

            var context = new SerializationContext(dockControl)
            {
                SaveNonPersistentItems = !excludeNonPersistentItems,
            };

            // Create root node.
            XElement root = new XElement("DockControl");

            // Save properties of DockControl.
            root.Add(new XAttribute("IsLocked", dockControl.IsLocked));

            // Serialize all DockTabItems.
            {
                var xElement = new XElement("DockTabItems");
                var items = dockControl.GetDockElements()
                                       .OfType<IDockTabItem>()
                                       .Distinct()
                                       .OrderBy(item => item.DockId);
                foreach (var item in items)
                {
                    if (excludeNonPersistentItems && !item.IsPersistent)  // Ignore non-persistent items?
                        continue;
                    if (item.DockId == null)
                        throw new DockException("Could not save docking layout. IDockTabItem does not have a valid DockId.");

                    xElement.Add(Save(context, item, false));
                }

                root.Add(xElement);
            }

            // Serialize root pane.
            {
                var xElement = new XElement("RootPane");
                xElement.Add(Save(context, dockControl.RootPane));
                root.Add(xElement);
            }

            // Serialize float windows.
            {
                var xElement = new XElement("FloatWindows");
                if (dockControl.FloatWindows != null)
                    foreach (var floatWindow in dockControl.FloatWindows)
                        xElement.Add(Save(context, floatWindow));
                root.Add(xElement);
            }

            // Serialize auto-hide panes.
            {
                var autoHideBars = new[]
                {
                    new { Bar = dockControl.AutoHideLeft,  Name = "AutoHideLeft" },
                    new { Bar = dockControl.AutoHideRight,  Name = "AutoHideRight" },
                    new { Bar = dockControl.AutoHideTop,  Name = "AutoHideTop" },
                    new { Bar = dockControl.AutoHideBottom,  Name = "AutoHideBottom" },
                };

                foreach (var bar in autoHideBars)
                {
                    var xElement = new XElement(bar.Name);
                    if (bar.Bar != null)
                        foreach (var pane in bar.Bar)
                            xElement.Add(Save(context, pane));
                    root.Add(xElement);
                }
            }

            return root;
        }
Exemplo n.º 22
0
        private void UnregisterEventHandlers(IDockControl dataContext)
        {
            if (dataContext == null)
                return;

            // Detach from IDockControl.
            DockStrategy = null;
            PropertyChangedEventManager.RemoveHandler(dataContext, OnDockStrategyChanged, nameof(IDockControl.DockStrategy));
            PropertyChangedEventManager.RemoveHandler(dataContext, OnActiveItemChanged, nameof(IDockControl.ActiveDockTabItem));
            //PropertyChangedEventManager.RemoveHandler(dataContext, OnActivePaneChanged, nameof(IDockControl.ActiveDockTabPane));

            var collectionView = CollectionViewSource.GetDefaultView(dataContext.FloatWindows);
            CollectionChangedEventManager.RemoveHandler(collectionView, OnFloatWindowsChanged);
        }
Exemplo n.º 23
0
 public static XElement Save(IDockControl dockControl)
 {
     return(Save(dockControl, false));
 }
Exemplo n.º 24
0
        public static void Load(IDockControl dockControl, XElement storedLayout /*, bool keepDockTabItems */)
        {
            ///// <param name="keepDockTabItems">
            ///// If set to <see langword="true"/> all existing <see cref="IDockTabItem"/>s are kept. If
            ///// set to <see langword="false"/>, all current <see cref="IDockTabItem"/>s are closed
            ///// before the new layout is loaded.
            ///// </param>

            if (dockControl == null)
            {
                throw new ArgumentNullException(nameof(dockControl));
            }
            if (storedLayout == null)
            {
                throw new ArgumentNullException(nameof(storedLayout));
            }

            var dockStrategy = dockControl.DockStrategy;

            if (dockStrategy == null)
            {
                throw new ArgumentException("The IDockControl does not have a DockStrategy.");
            }

            const bool keepNonPersistentItems = true;  // Non-persistent items are usually documents and should be kept.
            const bool keepPersistentItems    = false; // Persistent items are usually tool windows.

            // Remember current dock items (visible and hidden items).
            var items = dockControl.GetDockElements()
                        .OfType <IDockTabItem>()
                        .Distinct()
                        .ToArray();

            // Validate DockIds.
            foreach (var item in items)
            {
                if (item.DockId == null)
                {
                    throw new DockException("Could not load docking layout. IDockTabItem does not have a valid DockId.");
                }
            }

            // Check for duplicate DockIds.
            bool duplicateDockIds = items.GroupBy(item => item.DockId)
                                    .Select(group => group.Count())
                                    .Any(count => count > 1);

            if (duplicateDockIds)
            {
                throw new DockException("Could not load docking layout. Two or more IDockTabItems have the same DockId.");
            }

            var context = new DeserializationContext {
                DockControl = dockControl
            };

            dockStrategy.Begin();
            try
            {
                // Remember current IDockTabItems.
                // context.OldItems stores all (because OldItems is used in LoadDockTabItem).
                // Another list stores only the old items which are visible.
                var oldVisibleItems = new List <IDockTabItem>();
                foreach (var item in items)
                {
                    context.OldItems[item.DockId] = item;

                    if (item.DockState != DockState.Hide)
                    {
                        oldVisibleItems.Add(item);
                    }
                }

                // Load IDockTabItems. Do not add to the dock control yet.
                foreach (var itemXElement in storedLayout.Elements("DockTabItems").Elements())
                {
                    var item = LoadDockTabItem(context, itemXElement, onlyReference: false);
                    if (item != null)
                    {
                        context.NewItems[item.DockId] = item;
                    }
                }

                // Try to close all IDockTabItems which we will not keep or which will be hidden.
                // We keep a list of items which we need to keep open.
                var oldItemsToShow = new List <IDockTabItem>();
                foreach (var oldDockTabItem in oldVisibleItems)
                {
                    if (context.NewItems.ContainsKey(oldDockTabItem.DockId) &&
                        oldDockTabItem.DockState != DockState.Hide)
                    {
                        // Item remains in the layout and visible.
                        continue;
                    }

                    // Previously visible item is removed from layout or hidden.
                    // Try to close it. Items that cannot be closed will be shown at the end.
                    bool closed = false;
                    if ((oldDockTabItem.IsPersistent && !keepPersistentItems) ||
                        (!oldDockTabItem.IsPersistent && !keepNonPersistentItems))
                    {
                        if (dockStrategy.CanClose(oldDockTabItem))
                        {
                            // Successfully closed.
                            dockStrategy.Close(oldDockTabItem);
                            closed = true;
                        }
                    }

                    if (!closed)
                    {
                        oldItemsToShow.Add(oldDockTabItem);
                    }
                }

                // The DockControl still contains the old layout with the previous IDockPane
                // view model. The old view models are still attached to the DockControl and
                // react to changes, which may cause the wrong screen conduction.
                // --> Detach IDockTabItems from old layout.
                foreach (var item in items)
                {
                    DockHelper.Remove(dockControl, item);
                }

                dockControl.FloatWindows.Clear();
                dockControl.AutoHideLeft.Clear();
                dockControl.AutoHideRight.Clear();
                dockControl.AutoHideTop.Clear();
                dockControl.AutoHideBottom.Clear();

                var isLocked = (bool?)context.Checked(storedLayout.Attribute("IsLocked"));
                if (isLocked != null)
                {
                    dockControl.IsLocked = isLocked.Value;
                }

                // Load float windows.
                {
                    foreach (var xElement in storedLayout.Elements("FloatWindows").Elements())
                    {
                        var floatWindow = LoadFloatWindow(context, xElement);
                        if (floatWindow != null)
                        {
                            dockControl.FloatWindows.Add(floatWindow);
                        }
                    }
                }

                // Load auto-hide panes.
                {
                    var autoHideBars = new[]
                    {
                        new { Bar = dockControl.AutoHideLeft, Name = "AutoHideLeft" },
                        new { Bar = dockControl.AutoHideRight, Name = "AutoHideRight" },
                        new { Bar = dockControl.AutoHideTop, Name = "AutoHideTop" },
                        new { Bar = dockControl.AutoHideBottom, Name = "AutoHideBottom" },
                    };

                    foreach (var bar in autoHideBars)
                    {
                        foreach (var xElement in storedLayout.Elements(bar.Name).Elements())
                        {
                            var dockPane = LoadDockPane(context, xElement);
                            if (dockPane != null)
                            {
                                bar.Bar.Add((IDockTabPane)dockPane);
                            }
                        }
                    }
                }

                // Load root pane. (We do this after loading the float windows and auto-hide bars,
                // because the dock strategy might want to activate an item in a float window or
                // auto-hide bar).
                dockControl.RootPane = LoadDockPane(context, storedLayout.Elements("RootPane").Elements().FirstOrDefault());

                // Run cleanup to update IsVisible flags. Those should be up-to-date before calling
                // Show() to find good default dock target positions.
                dockStrategy.Cleanup();

                // This is not done in cleanup if we are inside Begin()/End().
                dockControl.ActiveDockTabPane = null;
                dockControl.ActiveDockTabItem = null;

                // Show all old items that are not visible in the loaded layout but could not be closed.
                foreach (var item in oldItemsToShow)
                {
                    dockStrategy.Show(item);
                }

                // Activate item.
                if (context.ActiveItem != null)
                {
                    dockStrategy.Show(context.ActiveItem);
                }

                context.ResetLineInfo();
            }
            catch (Exception exception)
            {
                var message = "Could not load docking layout.";

                if (context.LineInfo != null && context.LineInfo.HasLineInfo())
                {
                    message += Invariant($" Error at line {context.LineInfo.LineNumber}, column {context.LineInfo.LinePosition}.");
                }

                message += " See inner exception for more details.";

                throw new DockException(message, exception);
            }
            finally
            {
                dockStrategy.End();
            }
        }
Exemplo n.º 25
0
        public static XElement Save(IDockControl dockControl, bool excludeNonPersistentItems)
        {
            if (dockControl == null)
            {
                throw new ArgumentNullException(nameof(dockControl));
            }
            if (dockControl.DockStrategy == null)
            {
                throw new ArgumentException("The dock control does not have a dock strategy.");
            }

            var context = new SerializationContext(dockControl)
            {
                SaveNonPersistentItems = !excludeNonPersistentItems,
            };

            // Create root node.
            XElement root = new XElement("DockControl");

            // Save properties of DockControl.
            root.Add(new XAttribute("IsLocked", dockControl.IsLocked));

            // Serialize all DockTabItems.
            {
                var xElement = new XElement("DockTabItems");
                var items    = dockControl.GetDockElements()
                               .OfType <IDockTabItem>()
                               .Distinct()
                               .OrderBy(item => item.DockId);
                foreach (var item in items)
                {
                    if (excludeNonPersistentItems && !item.IsPersistent)  // Ignore non-persistent items?
                    {
                        continue;
                    }
                    if (item.DockId == null)
                    {
                        throw new DockException("Could not save docking layout. IDockTabItem does not have a valid DockId.");
                    }

                    xElement.Add(Save(context, item, false));
                }

                root.Add(xElement);
            }

            // Serialize root pane.
            {
                var xElement = new XElement("RootPane");
                xElement.Add(Save(context, dockControl.RootPane));
                root.Add(xElement);
            }

            // Serialize float windows.
            {
                var xElement = new XElement("FloatWindows");
                if (dockControl.FloatWindows != null)
                {
                    foreach (var floatWindow in dockControl.FloatWindows)
                    {
                        xElement.Add(Save(context, floatWindow));
                    }
                }
                root.Add(xElement);
            }

            // Serialize auto-hide panes.
            {
                var autoHideBars = new[]
                {
                    new { Bar = dockControl.AutoHideLeft, Name = "AutoHideLeft" },
                    new { Bar = dockControl.AutoHideRight, Name = "AutoHideRight" },
                    new { Bar = dockControl.AutoHideTop, Name = "AutoHideTop" },
                    new { Bar = dockControl.AutoHideBottom, Name = "AutoHideBottom" },
                };

                foreach (var bar in autoHideBars)
                {
                    var xElement = new XElement(bar.Name);
                    if (bar.Bar != null)
                    {
                        foreach (var pane in bar.Bar)
                        {
                            xElement.Add(Save(context, pane));
                        }
                    }
                    root.Add(xElement);
                }
            }

            return(root);
        }
Exemplo n.º 26
0
        private void RegisterEventHandlers(IDockControl dataContext)
        {
            if (dataContext == null)
                return;

            // Attach to IDockControl.
            if (dataContext.DockStrategy == null)
                throw new DockException("IDockControl.DockStrategy must not be null.");

            DockStrategy = dataContext.DockStrategy;

            // Observe IDockControl properties.
            PropertyChangedEventManager.AddHandler(dataContext, OnDockStrategyChanged, nameof(IDockControl.DockStrategy));
            PropertyChangedEventManager.AddHandler(dataContext, OnActiveItemChanged, nameof(IDockControl.ActiveDockTabItem));
            //PropertyChangedEventManager.AddHandler(dataContext, OnActivePaneChanged, nameof(IDockControl.ActiveDockTabPane));

            // The ICollectionView is used to filter IFloatWindows.
            var collectionView = CollectionViewSource.GetDefaultView(dataContext.FloatWindows);
            var collectionViewLiveShaping = collectionView as ICollectionViewLiveShaping;
            if (collectionViewLiveShaping != null && collectionViewLiveShaping.CanChangeLiveFiltering)
            {
                collectionViewLiveShaping.LiveFilteringProperties.Clear();
                collectionViewLiveShaping.LiveFilteringProperties.Add(nameof(IFloatWindow.IsVisible));
                collectionViewLiveShaping.IsLiveFiltering = true;
                collectionView.Filter = floatWindow => ((IFloatWindow)floatWindow).IsVisible;
            }
            CollectionChangedEventManager.AddHandler(collectionView, OnFloatWindowsChanged);
        }