private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            DockPane pane = new DockPane();
            pane.MinHeight = 24;
            pane.MinWidth = 100;
            pane.Header = "Solution Explorer";
            Grid g = new Grid();
            g.Background = Brushes.White;
            TextBlock text = new TextBlock();
            text.Text = "Some content - " + (i + 1);
            g.Children.Add(text);
            pane.Content = g;
            Dock direction = Dock.Top;
            if (i % 4 == 1)
                direction = Dock.Right;
            else if (i % 4 == 2)
                direction = Dock.Left;
            else if (i % 4 == 3)
                direction = Dock.Bottom;
            i++;

            pane.Tag = i;

            pane.MouseEnter += (a, b) =>
                {
                    var x = WindowsManager;
                    System.Diagnostics.Debug.WriteLine((a as DockPane).Tag);
                };

            WindowsManager.AddPinnedWindow(pane, direction);
        }
        /// <summary>
        /// Called when dock pane drag has started
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void OnPaneDragStarted(object sender, MouseButtonEventArgs e)
        {
            ActiveWindowsManager = this;
            DraggedPane = sender as DockPane;
            _dockPaneDragging = true;
            _dragStartPointOffset = (e != null) ? e.GetPosition(DraggedPane) : Mouse.GetPosition(this);

            // Show the visibility
            DockingPanel.Visibility = Visibility.Visible;

            RemoveCondencedDockPanel(DraggedPane.CondencedDockPanel);
            RemovePinnedWindow(DraggedPane);

            // Dim the dragged window
            DraggedPane.Opacity = 0.25;

            if (DraggedPane.DockPaneState != DockPaneState.Floating)
            {
                IgnoreStateChangeForDockPane(DraggedPane);

                Point panePosition = e != null ? e.GetPosition(this) : Mouse.GetPosition(this);

                Canvas.SetTop(DraggedPane, panePosition.Y);
                Canvas.SetLeft(DraggedPane, panePosition.X);
                FloatingPanel.Children.Add(DraggedPane);
                MonitorStateChangeForDockPane(DraggedPane);

                // Set this last since until the DraggedPane is not added
                // to the FloatingPanel it will not be in the visual tree
                // and hence things like adorner layer will not be present
                DraggedPane.DockPaneState = DockPaneState.Floating;
            }

            DraggedPane.IsHitTestVisible = false;

            // This is necessary or when tab items are floated again
            // mouse up event never fires
            Mouse.Capture(this, CaptureMode.SubTree);
        }
        /// <summary>
        /// Removes the pinned window
        /// </summary>
        /// <param name="pane">Dock pane</param>
        private void RemovePinnedWindow(DockPane pane)
        {
            DockPanel logicalParentDockPanel = LogicalTreeHelper.GetParent(pane) as DockPanel;

            if (logicalParentDockPanel == null)
            {
                return;
            }

            int indexOfPane = logicalParentDockPanel.Children.IndexOf(pane);

            GridSplitter splitter = logicalParentDockPanel.Children[indexOfPane + 1] as GridSplitter;
            logicalParentDockPanel.Children.Remove(pane);
            logicalParentDockPanel.Children.Remove(splitter);
        }
        /// <summary>
        /// Adds the floating window.
        /// </summary>
        /// <param name="pane">The pane.</param>
        public void AddFloatingWindow(DockPane pane)
        {
            DetachDockPaneEvents(pane);
            AttachDockPaneEvents(pane);

            if (Mouse.LeftButton == MouseButtonState.Pressed)
            {
                // Setting state to non-floating so that OnPaneDragStared can
                // set it to floating and execute related effects
                pane.DockPaneState = DockPaneState.Content;
                OnPaneDragStarted(pane, null);
            }
            else
            {
                pane.DockPaneState = DockPaneState.Floating;
                FloatingPanel.Children.Add(pane);
                MonitorStateChangeForDockPane(pane);
            }
        }
 /// <summary>
 /// Monitors the state change for dock pane and ensures that
 /// only one instance of pane is monitored to prevent redundent events
 /// </summary>
 /// <param name="pane">Pane to monitor</param>
 private void MonitorStateChangeForDockPane(DockPane pane)
 {
     if ((pane != null) && (!_dockPaneStateMonitorList.Contains(pane)))
     {
         _dockPaneStateMonitorList.Add(pane);
     }
 }
        /// <summary>
        /// Splits and adds document to the split window
        /// </summary>
        /// <param name="pane">The pane</param>
        /// <param name="dockPoint">The dock point</param>
        private void SplitAndAddDocument(DockPane pane, ContentDockPoint dockPoint)
        {
            DocumentContainer container = new DocumentContainer();
            Grid splitGrid = null;

            switch (dockPoint)
            {
                case ContentDockPoint.Top:
                    splitGrid = SplitVertically(false);
                    Grid.SetRow(container, 0);
                    break;
                case ContentDockPoint.Left:
                    splitGrid = SplitHorizontally(false);
                    Grid.SetColumn(container, 0);
                    break;
                case ContentDockPoint.Right:
                    splitGrid = SplitHorizontally(true);
                    Grid.SetColumn(container, 2);
                    break;
                case ContentDockPoint.Bottom:
                    splitGrid = SplitVertically(true);
                    Grid.SetRow(container, 2);
                    break;
                case ContentDockPoint.Content:
                    AddDocument(pane);
                    return;
                default:
                    break;
            }

            container.AddDocument(pane);
            splitGrid.Children.Add(container);
        }
        /// <summary>
        /// Reads the dock pane from the xml element
        /// </summary>
        /// <param name="dockPaneElement">The dock pane xml element.</param>
        /// <returns>Newly constructed DockPane</returns>
        private DockPane ReadDockPane(XmlElement dockPaneElement)
        {
            DockPane dockPane = new DockPane();
            _dockPaneReader(dockPane, dockPaneElement.GetAttribute("Data"));

            double height = double.Parse(dockPaneElement.GetAttribute("Height"));
            dockPane.Height = height;

            double width = double.Parse(dockPaneElement.GetAttribute("Width"));
            dockPane.Width = width;

            XmlAttribute topAttribute = dockPaneElement.Attributes.GetNamedItem("Top") as XmlAttribute;
            if (topAttribute != null)
            {
                Canvas.SetTop(dockPane, double.Parse(topAttribute.Value));
            }

            XmlAttribute leftAttribute = dockPaneElement.Attributes.GetNamedItem("Left") as XmlAttribute;
            if (leftAttribute != null)
            {
                Canvas.SetLeft(dockPane, double.Parse(leftAttribute.Value));
            }

            return dockPane;
        }
        /// <summary>
        /// Adds the pinned window to top of content
        /// </summary>
        /// <param name="pane">Pane to add</param>
        private void AddPinnedWindowToTop(DockPane pane)
        {
            DockPanel.SetDock(pane, Dock.Top);
            pane.Width = double.NaN;
            TopPinnedWindows.Children.Add(pane);

            GridSplitter sizingThumb = new GridSplitter();
            sizingThumb.Height = 4;
            sizingThumb.HorizontalAlignment = HorizontalAlignment.Stretch;
            sizingThumb.Background = Brushes.Transparent;
            sizingThumb.Cursor = Cursors.SizeNS;
            DockPanel.SetDock(sizingThumb, Dock.Top);
            TopPinnedWindows.Children.Add(sizingThumb);

            sizingThumb.DragDelta += (a, b) =>
            {
                if (pane.Height.Equals(double.NaN))
                {
                    pane.Height = pane.DesiredSize.Height;
                }

                if (pane.Height + b.VerticalChange <= 0)
                {
                    return;
                }

                pane.Height += b.VerticalChange;
            };
        }
        /// <summary>
        /// Attaches the events to dock pane
        /// </summary>
        /// <param name="pane">Dock pane</param>
        private void AttachDockPaneEvents(DockPane pane)
        {
            pane.Close += OnDockPaneClosed;

            MonitorStateChangeForDockPane(pane);

            pane.HeaderDrag += OnPaneDragStarted;
        }
        /// <summary>
        /// Adds the pinned window without manipulating events
        /// </summary>
        /// <param name="pane">The pane.</param>
        /// <param name="dock">The dock.</param>
        private void AddPinnedWindowInner(DockPane pane, Dock dock)
        {
            switch (dock)
            {
                case Dock.Bottom:
                    AddPinnedWindowToBottom(pane);
                    break;
                case Dock.Left:
                    AddPinnedWindowToLeft(pane);
                    break;
                case Dock.Right:
                    AddPinnedWindowToRight(pane);
                    break;
                case Dock.Top:
                    AddPinnedWindowToTop(pane);
                    break;
                default:
                    break;
            }

            pane.DockPaneState = DockPaneState.Docked;
        }
        /// <summary>
        /// Adds the pinned window to right of content
        /// </summary>
        /// <param name="pane">Pane to add</param>
        private void AddPinnedWindowToRight(DockPane pane)
        {
            DockPanel.SetDock(pane, Dock.Right);
            pane.Height = double.NaN;
            RightPinnedWindows.Children.Add(pane);

            GridSplitter sizingThumb = new GridSplitter();
            sizingThumb.Width = 4;
            sizingThumb.Background = Brushes.Transparent;
            sizingThumb.Cursor = Cursors.SizeWE;
            DockPanel.SetDock(sizingThumb, Dock.Right);
            RightPinnedWindows.Children.Add(sizingThumb);

            sizingThumb.DragDelta += (a, b) =>
            {
                if (pane.Width.Equals(double.NaN))
                {
                    pane.Width = pane.DesiredSize.Width;
                }

                if (pane.Width - b.HorizontalChange <= 0)
                {
                    return;
                }

                pane.Width -= b.HorizontalChange;
            };
        }
        /// <summary>
        /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseUp"/> routed event 
        /// reaches an element in its route that is derived from this class. Implement this method to add class 
        /// handling for this event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs"/> that contains the event data. 
        /// The event data reports that the mouse button was released.</param>
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            base.OnMouseUp(e);

            if (!_dockPaneDragging)
            {
                return;
            }

            ReleaseMouseCapture();

            DraggedPane.Opacity = 1;
            _dockPaneDragging = false;
            DockingPanel.Visibility = Visibility.Collapsed;

            DraggedPane.IsHitTestVisible = true;

            DraggedPane = null;
            ActiveWindowsManager = null;
        }
 /// <summary>
 /// Removes the dock pane from windows manager alltogether and unsubscribes from all events
 /// </summary>
 /// <param name="pane">The pane.</param>
 public void RemoveDockPane(DockPane pane)
 {
     DetachDockPaneEvents(pane);
     RemoveCondencedDockPanel(DraggedPane.CondencedDockPanel);
     RemovePinnedWindow(DraggedPane);
     FloatingPanel.Children.Remove(pane);
 }
        /// <summary>
        /// Adds the dock pane.
        /// </summary>
        /// <param name="pane">The pane.</param>
        /// <param name="dock">The dock.</param>
        public void AddPinnedWindow(DockPane pane, Dock dock)
        {
            AddPinnedWindowInner(pane, dock);

            DetachDockPaneEvents(pane);
            AttachDockPaneEvents(pane);
        }
 /// <summary>
 /// Adds the dock pane to the document container via splitting and docks it to the specified dock point
 /// </summary>
 /// <param name="pane">Pane to add</param>
 /// <param name="dockPoint">The dock point for content</param>
 public void AddDockPane(DockPane pane, ContentDockPoint dockPoint)
 {
     DocumentContainer targetContainer;
     if (CanMergeContent(dockPoint, out targetContainer))
     {
         targetContainer.AddDocument(pane);
     }
     else
     {
         SplitAndAddDocument(pane, dockPoint);
     }
 }
        /// <summary>
        /// Condences the dock panel
        /// </summary>
        /// <param name="pane">The pane.</param>
        /// <param name="dock">The dock.</param>
        private void CondenceDockPanel(DockPane pane, Dock dock)
        {
            FrameworkElement condencedDockPanel = pane.CondencedDockPanel;
            condencedDockPanel.LayoutTransform = (dock == Dock.Left) || (dock == Dock.Right) ? new RotateTransform(90) : null;

            switch (dock)
            {
                case Dock.Bottom:
                    BottomWindowHeaders.Children.Add(condencedDockPanel);
                    break;
                case Dock.Left:
                    LeftWindowHeaders.Children.Add(condencedDockPanel);
                    break;
                case Dock.Right:
                    RightWindowHeaders.Children.Add(condencedDockPanel);
                    break;
                case Dock.Top:
                    TopWindowHeaders.Children.Add(condencedDockPanel);
                    break;
                default:
                    break;
            }

            DockPanel.SetDock(pane, dock);
            DetachEvents(condencedDockPanel);
            pane.DockPaneState = DockPaneState.AutoHide;
            AttachEvents(condencedDockPanel);
        }
        /// <summary>
        /// Adds the dock panel as a document
        /// </summary>
        /// <param name="pane">The pane</param>
        public void AddDocument(DockPane pane)
        {
            DocumentContent documentContent = new DocumentContent(pane, RemoveDocumentCommand);
            pane.DockPaneState = DockPaneState.Content;
            Documents.Add(documentContent);

            if (DocumentsTab != null)
            {
                DocumentsTab.SelectedItem = documentContent;
            }

            State = DocumentContainerState.ContainsDocuments;
        }
        /// <summary>
        /// Detaches the events from the dock pane
        /// </summary>
        /// <param name="pane">The pane.</param>
        private void DetachDockPaneEvents(DockPane pane)
        {
            pane.Close -= OnDockPaneClosed;

            IgnoreStateChangeForDockPane(pane);

            pane.HeaderDrag -= OnPaneDragStarted;
        }
        /// <summary>
        /// Reads the documents for current document container
        /// </summary>
        /// <param name="documentContainer">The document container.</param>
        protected override void ReadDocuments(DocumentContainer documentContainer)
        {
            ValidateStackNotEmpty();

            XmlElement documentContainerElement = _elementStack.Peek();
            Validate.Assert<InvalidOperationException>(documentContainerElement.Name == "DocumentContainer");

            foreach (XmlElement documentElement in documentContainerElement.SelectNodes(@"Document").OfType<XmlElement>())
            {
                DockPane dockPane = new DockPane();
                _dockPaneReader(dockPane, documentElement.GetAttribute("Data"));
                documentContainer.AddDocument(dockPane);
            }
        }
 /// <summary>
 /// Ignores the state change for dock pane.
 /// </summary>
 /// <param name="pane">Dock pane to ignore state changes from</param>
 private void IgnoreStateChangeForDockPane(DockPane pane)
 {
     if (pane != null)
     {
         _dockPaneStateMonitorList.Remove(pane);
     }
 }
Beispiel #21
0
        /// <summary>
        /// Called when dock pane state has changed
        /// </summary>
        /// <param name="pane">Dock pane.</param>
        /// <param name="state">New state (may not be current yet)</param>
        private static void OnDockPaneStateChange(DockPane pane, DockPaneState state)
        {
            switch (state)
            {
                case DockPaneState.Docked:

                    pane.ClearAdornerLayer();

                    if (pane.PinButton != null)
                    {
                        pane.PinButton.Visibility = Visibility.Visible;
                        pane.PinButton.IsChecked = false;
                    }
                    break;

                case DockPaneState.AutoHide:

                    pane.ClearAdornerLayer();

                    if (pane.PinButton != null)
                    {
                        pane.PinButton.Visibility = Visibility.Visible;
                        pane.PinButton.IsChecked = true;
                    }
                    break;

                case DockPaneState.Floating:

                    pane.AddResizingAdorner();

                    if (pane.PinButton != null)
                    {
                        pane.PinButton.Visibility = Visibility.Collapsed;
                    }
                    break;

                case DockPaneState.Content:

                    pane.ClearAdornerLayer();
                    break;

                default:
                    break;
            }
        }
        /// <summary>
        /// Adds the window in auto hide fashion
        /// </summary>
        /// <param name="pane">The pane.</param>
        /// <param name="dock">The dock.</param>
        public void AddAutoHideWindow(DockPane pane, Dock dock)
        {
            CondenceDockPanel(pane, dock);

            DetachDockPaneEvents(pane);
            AttachDockPaneEvents(pane);
        }