/// <summary> /// Anchor a document pane (<see cref="DocumentPane"/>) to a border of an other document pane /// </summary> /// <param name="paneToAnchor">Pane to anchor</param> /// <param name="relativePane">Pane relative</param> /// <param name="anchor"></param> public void Anchor(DocumentPane paneToAnchor, DocumentPane relativePane, AnchorStyle anchor) { //ensure that content property is not empty EnsureContentNotEmpty(); if (anchor == AnchorStyle.None) anchor = AnchorStyle.Right; //get a reference to the resizingpanel container of relativePane ResizingPanel relativePaneContainer = LogicalTreeHelper.GetParent(relativePane) as ResizingPanel; DocumentPaneResizingPanel relativeDocumentPaneContainer = relativePane.GetParentDocumentPaneResizingPanel(); Orientation requestedOrientation = (anchor == AnchorStyle.Bottom || anchor == AnchorStyle.Top) ? Orientation.Vertical : Orientation.Horizontal; if (relativePaneContainer == null) { Debug.Assert(relativePane.Parent == this); relativeDocumentPaneContainer = new DocumentPaneResizingPanel(); relativePaneContainer = relativeDocumentPaneContainer; relativeDocumentPaneContainer.Orientation = requestedOrientation; this.Content = relativePaneContainer; relativePaneContainer.Children.Add(relativePane); } if (relativeDocumentPaneContainer == null) { relativeDocumentPaneContainer = new DocumentPaneResizingPanel(); relativeDocumentPaneContainer.Orientation = requestedOrientation; int indexOfPaneToReplace = relativePaneContainer.Children.IndexOf(relativePane); relativePaneContainer.Children.RemoveAt(indexOfPaneToReplace); relativeDocumentPaneContainer.Children.Add(relativePane); relativePaneContainer.Children.Insert(indexOfPaneToReplace, relativeDocumentPaneContainer); relativePaneContainer = relativeDocumentPaneContainer; } Debug.Assert(relativePaneContainer != null, "By now we can't have a pane without a resizing panel containing it"); #region Create and setup container panel if (relativePaneContainer != null) { //check if orientation is right if (relativePaneContainer.Orientation != requestedOrientation) { //if the existing panel is not oriented as we want //create a new one DocumentPaneResizingPanel newPanel = new DocumentPaneResizingPanel(); newPanel.Orientation = requestedOrientation; //replace relative pane in its' container panel //with this new panel int indexofRelativePane = relativePaneContainer.Children.IndexOf(relativePane); relativePaneContainer.Children.Remove(relativePane); relativePaneContainer.Children.Insert(indexofRelativePane, newPanel); //now we have a panel correctly placed in the tree newPanel.Children.Add(relativePane); //use InsertChildRelativeTo function to add a resizingsplitter between //the two children newPanel.InsertChildRelativeTo( paneToAnchor, relativePane, anchor == AnchorStyle.Right || anchor == AnchorStyle.Bottom); relativePaneContainer = newPanel; } else { if (anchor == AnchorStyle.Left || anchor == AnchorStyle.Top) { //add new child before first (prepend) relativePaneContainer.InsertChildRelativeTo(paneToAnchor, relativePane, false); } else { //add new child after last (append) relativePaneContainer.InsertChildRelativeTo(paneToAnchor, relativePane, true); } //if (relativePaneContainer.Orientation == Orientation.Horizontal) //{ // Size desideredSize = ResizingPanel.GetEffectiveSize(paneToAnchor); // double approxStarForNewPane = desideredSize.Width / relativePaneContainer.ActualWidth; // approxStarForNewPane = Math.Min(approxStarForNewPane, 1.0); // paneToAnchor.SetValue(ResizingPanel.ResizeWidthProperty, new GridLength(approxStarForNewPane, GridUnitType.Star)); //} } relativePaneContainer.InvalidateMeasure(); } #endregion //paneToAnchor.Focus(); //(paneToAnchor.SelectedItem as ManagedContent).Activate(); //if (paneToAnchor.SelectedItem is DocumentContent) // ActiveDocument = paneToAnchor.SelectedItem as DocumentContent; paneToAnchor.SelectedIndex = 0; }
/// <summary> /// Anchor a dockable pane (<see cref="DockablePane"/>) to a border of a document pane /// </summary> /// <param name="paneToAnchor">Pane to anchor</param> /// <param name="relativePane">Pane relative</param> /// <param name="anchor"></param> public void Anchor(DockablePane paneToAnchor, DocumentPane relativePane, AnchorStyle anchor) { //ensure that content property is not empty EnsureContentNotEmpty(); if (anchor == AnchorStyle.None) anchor = AnchorStyle.Right; //get a reference to the resizingpanel container of relativePane ResizingPanel relativePaneContainer = LogicalTreeHelper.GetParent(relativePane) as ResizingPanel; DocumentPaneResizingPanel relativeDocumentPaneContainer = relativePane.GetParentDocumentPaneResizingPanel(); Orientation requestedOrientation = (anchor == AnchorStyle.Bottom || anchor == AnchorStyle.Top) ? Orientation.Vertical : Orientation.Horizontal; if (relativePaneContainer == null) { Debug.Assert(relativePane.Parent == this); this.Content = null; relativeDocumentPaneContainer = new DocumentPaneResizingPanel(); relativeDocumentPaneContainer.Children.Add(relativePane); relativePaneContainer = new ResizingPanel(); relativePaneContainer.Orientation = requestedOrientation; this.Content = relativePaneContainer; relativePaneContainer.Children.Add(relativeDocumentPaneContainer); } if (relativeDocumentPaneContainer == null) { relativeDocumentPaneContainer = new DocumentPaneResizingPanel(); relativeDocumentPaneContainer.Orientation = requestedOrientation; int indexOfPaneToReplace = relativePaneContainer.Children.IndexOf(relativePane); relativePaneContainer.Children.RemoveAt(indexOfPaneToReplace); relativeDocumentPaneContainer.Children.Add(relativePane); relativePaneContainer.Children.Insert(indexOfPaneToReplace, relativeDocumentPaneContainer); } relativePaneContainer = LogicalTreeHelper.GetParent(relativeDocumentPaneContainer) as ResizingPanel; //Debug.Assert(relativePaneContainer is DocumentPaneResizingPanel, "By now we can't have a pane without a resizing panel containing it"); if (relativePaneContainer == null) { Debug.Assert(relativeDocumentPaneContainer.Parent == this); this.Content = null; relativePaneContainer = new ResizingPanel(); relativePaneContainer.Orientation = requestedOrientation; this.Content = relativePaneContainer; relativePaneContainer.Children.Add(relativeDocumentPaneContainer); } #region Create and setup container panel if (relativePaneContainer != null) { //check if orientation is right if (relativePaneContainer.Orientation != requestedOrientation) { //if the existing panel is not oriented as we want //create a new one ResizingPanel newPanel = new ResizingPanel(); newPanel.Orientation = requestedOrientation; if (newPanel.Orientation == Orientation.Horizontal) ResizingPanel.SetResizeHeight(newPanel, ResizingPanel.GetResizeHeight(relativePane)); else ResizingPanel.SetResizeWidth(newPanel, ResizingPanel.GetResizeWidth(relativePane)); //replace relative pane in its' container panel //with this new panel int indexofRelativePane = relativePaneContainer.Children.IndexOf(relativeDocumentPaneContainer); relativePaneContainer.Children.Remove(relativeDocumentPaneContainer); relativePaneContainer.Children.Insert(indexofRelativePane, newPanel); //now we have a panel correctly placed in the tree newPanel.Children.Add(relativeDocumentPaneContainer); //use InsertChildRelativeTo function to add a resizingsplitter between //the two children newPanel.InsertChildRelativeTo( paneToAnchor, relativeDocumentPaneContainer, anchor == AnchorStyle.Right || anchor == AnchorStyle.Bottom); } else { if (anchor == AnchorStyle.Left || anchor == AnchorStyle.Top) { //add new child before first (prepend) relativePaneContainer.InsertChildRelativeTo(paneToAnchor, relativeDocumentPaneContainer, false); } else { //add new child after last (append) relativePaneContainer.InsertChildRelativeTo(paneToAnchor, relativeDocumentPaneContainer, true); } } } relativePaneContainer.InvalidateMeasure(); #endregion if (anchor == AnchorStyle.Left || anchor == AnchorStyle.Right) { double w = Math.Min( ResizingPanel.GetEffectiveSize(relativePane).Width / 2.0, ResizingPanel.GetEffectiveSize(paneToAnchor).Width); ResizingPanel.SetResizeWidth(paneToAnchor, new GridLength(w, GridUnitType.Pixel)); ResizingPanel.SetResizeHeight(paneToAnchor, new GridLength(1.0, GridUnitType.Star)); } else { double h = Math.Min( ResizingPanel.GetEffectiveSize(relativePane).Height / 2.0, ResizingPanel.GetEffectiveSize(paneToAnchor).Height); ResizingPanel.SetResizeWidth(paneToAnchor, new GridLength(1.0, GridUnitType.Star)); ResizingPanel.SetResizeHeight(paneToAnchor, new GridLength(h, GridUnitType.Pixel)); } //refresh contents state foreach (DockableContent draggedContent in paneToAnchor.Items) { draggedContent.SetStateToDock(); } //than set the new anchor style for the pane paneToAnchor.Anchor = anchor; //paneToAnchor.Focus(); }