public void ReadXml(System.Xml.XmlReader reader) { if (reader.ReadToFollowing(this.GetType().Name)) { String s = reader.GetAttribute(Orientation.GetType().Name); m_orientation = (Orientation)(Enum.Parse(Orientation.GetType(), s)); switch (m_orientation) { case Orientation.Horizontal: if (reader.ReadToDescendant("Column")) { RowDefinitions.Add(NewRowDefinition(new GridLength(1, GridUnitType.Star), m_minGridSize.Height)); do { double width = double.Parse(reader.GetAttribute("Width")); IDockLayout layout = null; reader.ReadStartElement(); if (reader.LocalName == typeof(DockedWindow).Name) { DockedWindow dockedWindow = new DockedWindow(Root, reader.ReadSubtree()); layout = dockedWindow.DockedContent.Children.Count != 0 ? dockedWindow : null; reader.ReadEndElement(); } else if (reader.LocalName == typeof(GridLayout).Name) { GridLayout gridLayout = new GridLayout(Root, reader.ReadSubtree()); layout = gridLayout.Layouts.Count > 0 ? gridLayout : null; reader.ReadEndElement(); } if (layout != null) { if (Children.Count > 0) { ColumnDefinitions.Add(NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Add(NewGridSplitter(Orientation)); } ColumnDefinitions.Add(NewColumnDefinition(new GridLength(width, GridUnitType.Star), m_minGridSize.Width)); m_children.Add(layout); Children.Add((FrameworkElement)layout); } } while (reader.ReadToNextSibling("Column")); } break; case Orientation.Vertical: if (reader.ReadToDescendant("Row")) { ColumnDefinitions.Add(NewColumnDefinition(new GridLength(1, GridUnitType.Star), m_minGridSize.Width)); do { double height = double.Parse(reader.GetAttribute("Height")); IDockLayout layout = null; reader.ReadStartElement(); if (reader.LocalName == typeof(DockedWindow).Name) { DockedWindow dockedWindow = new DockedWindow(Root, reader.ReadSubtree()); layout = dockedWindow.DockedContent.Children.Count != 0 ? dockedWindow : null; reader.ReadEndElement(); } else if (reader.LocalName == typeof(GridLayout).Name) { GridLayout gridLayout = new GridLayout(Root, reader.ReadSubtree()); layout = gridLayout.Layouts.Count > 0 ? gridLayout : null; reader.ReadEndElement(); } if (layout != null) { if (Children.Count > 0) { RowDefinitions.Add(NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Add(NewGridSplitter(Orientation)); } RowDefinitions.Add(NewRowDefinition(new GridLength(height, GridUnitType.Star), m_minGridSize.Height)); m_children.Add(layout); Children.Add((FrameworkElement)layout); } } while (reader.ReadToNextSibling("Row")); } break; } for(int i = 0; i < Children.Count; i++) { Grid.SetColumn(Children[i], Orientation == Orientation.Horizontal ? i : 0); Grid.SetRow(Children[i], Orientation == Orientation.Vertical ? i : 0); } reader.ReadEndElement(); } }
/// <summary> /// Will merge itself with given grid. Basicly it takes child grid, removes that grid, and all /// children of removed grid will be added to this grid. The child grid must have same orientation /// or maximum of 1 child. /// </summary> /// <param name="grid">Grid to merge with</param> internal void MergeWith(GridLayout grid) { // get the index of the grid to merge with (it is child of this grid) int index = m_children.IndexOf(grid); double totalValue = 0; int indexOffset = 0; if (Orientation == Orientation.Horizontal) { // get the column definition of child grid ColumnDefinition oldColumnDef = ColumnDefinitions[index * 2]; // count the sum of columns widths of childs children foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int columnIndex = Grid.GetColumn(element); ColumnDefinition layoutColumnDef = grid.ColumnDefinitions[columnIndex]; totalValue += layoutColumnDef.Width.Value; } // remove the child from our list, from view children adn from column definitions m_children.RemoveAt(index); Children.RemoveAt(index * 2); ColumnDefinitions.RemoveAt(index * 2); // move all childs children to this grid and create column definitions for each of them foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int columnIndex = Grid.GetColumn(element); ColumnDefinition layoutColumnDef = grid.ColumnDefinitions[columnIndex]; double newValue = oldColumnDef.Width.Value * layoutColumnDef.Width.Value / totalValue; ColumnDefinition newColumnDef = NewColumnDefinition(new GridLength(newValue, GridUnitType.Star), m_minGridSize.Width); grid.Children.Remove(element); ColumnDefinitions.Insert((index + indexOffset) * 2, newColumnDef); Children.Insert((index + indexOffset) * 2, element); m_children.Insert(index + indexOffset, newLayout); if (indexOffset < grid.Layouts.Count - 1) { // if we move more than one child, then we need to add new splitters too GridSplitter splitter = NewGridSplitter(Orientation.Horizontal); ColumnDefinitions.Insert((index + indexOffset) * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Insert((index + indexOffset) * 2 + 1, splitter); } indexOffset ++; } // set the association of column indexes for (int i = 0; i < Children.Count; i++) { Grid.SetColumn(Children[i], i); } } else { // get the row definition of child grid RowDefinition oldRowDef = RowDefinitions[index * 2]; // count the sum of row heights of childs children foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int RowIndex = Grid.GetRow(element); RowDefinition layoutRowDef = grid.RowDefinitions[RowIndex]; totalValue += layoutRowDef.Height.Value; } // remove the child from our list, from view children adn from row definitions m_children.RemoveAt(index); Children.RemoveAt(index * 2); RowDefinitions.RemoveAt(index * 2); // move all childs children to this grid and create row definitions for each of them foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int RowIndex = Grid.GetRow(element); RowDefinition layoutRowDef = grid.RowDefinitions[RowIndex]; double newValue = oldRowDef.Height.Value * layoutRowDef.Height.Value / totalValue; RowDefinition newRowDef = NewRowDefinition(new GridLength(newValue, GridUnitType.Star), m_minGridSize.Height); grid.Children.Remove(element); RowDefinitions.Insert((index + indexOffset) * 2, newRowDef); Children.Insert((index + indexOffset) * 2, element); m_children.Insert(index + indexOffset, newLayout); if (indexOffset < grid.Layouts.Count - 1) { // if we move more than one child, then we need to add new splitters too GridSplitter splitter = NewGridSplitter(Orientation.Vertical); RowDefinitions.Insert((index + indexOffset) * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Insert((index + indexOffset)* 2 + 1, splitter); } indexOffset ++; } // set the association of row indexes for (int i = 0; i < Children.Count; i++) { Grid.SetRow(Children[i], i); } } }
public void Dock(IDockContent nextTo, IDockContent newContent, DockTo dockTo) { IDockLayout targetChild = null; if (nextTo != null) { foreach (IDockLayout child in m_children) { if (child.HasChild(nextTo)) { targetChild = child; break; } } } if (targetChild == null) { foreach (IDockLayout child in m_children) { if (child.HasDescendant(nextTo)) { child.Dock(nextTo, newContent, dockTo); // child was docked, nothing else is necessary return; } } } if (dockTo == DockTo.Center && m_children.Count == 1) { m_children[0].Dock(null, newContent, dockTo); } else if (m_children.Count < 2) { if (dockTo == DockTo.Center) { dockTo = DockTo.Right; } if (dockTo == DockTo.Top || dockTo == DockTo.Bottom) { m_orientation = Orientation.Vertical; } else { m_orientation = Orientation.Horizontal; } DockedWindow newChild = new DockedWindow(Root, newContent); if (Children.Count == 0) { AddFirstChild(newChild); } else { if (targetChild == null) { if (dockTo == DockTo.Top || dockTo == DockTo.Left) { targetChild = m_children[0]; } else { targetChild = m_children[m_children.Count - 1]; } } FrameworkElement control = (FrameworkElement)targetChild; int index = m_children.IndexOf(targetChild); if (dockTo == DockTo.Left || dockTo == DockTo.Right) { GridSplitter splitter = NewGridSplitter(Orientation.Horizontal); int column = (int)control.GetValue(Grid.ColumnProperty); ColumnDefinition oldColumn = ColumnDefinitions[index * 2]; ContentSettings contentSettings = (newContent is TabLayout) ? ((TabLayout)newContent).Children[0].Settings : ((DockContent)newContent).Settings; double totalWidth = ((FrameworkElement)targetChild).ActualWidth; double width = Math.Max(Math.Min(contentSettings.Size.Width, (totalWidth - splitter.Width) / 2), (totalWidth - splitter.Width) / 5); double ratioNew = width / totalWidth; double ratioOld = (totalWidth - width - splitter.Width) / totalWidth; if (dockTo == DockTo.Left) { ColumnDefinition leftColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioNew, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinition rightColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioOld, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinitions[index * 2] = leftColumn; ColumnDefinitions.Insert(index * 2 + 1, rightColumn); ColumnDefinitions.Insert(index * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index, newChild); Children.Insert(index * 2, splitter); Children.Insert(index * 2, newChild); } else { ColumnDefinition leftColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioOld, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinition rightColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioNew, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinitions[index * 2] = leftColumn; ColumnDefinitions.Insert(index * 2 + 1, rightColumn); ColumnDefinitions.Insert(index * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index + 1, newChild); Children.Insert(index * 2 + 1, newChild); Children.Insert(index * 2 + 1, splitter); } for (int i = index * 2; i < Children.Count; i++) { Grid.SetColumn(Children[i], i); } } else { GridSplitter splitter = NewGridSplitter(Orientation.Vertical); int row = (int)control.GetValue(Grid.RowProperty); RowDefinition oldRow = RowDefinitions[index * 2]; ContentSettings contentSettings = (newContent is TabLayout) ? ((TabLayout)newContent).Children[0].Settings : ((DockContent)newContent).Settings; double totalHeight = ((FrameworkElement)targetChild).ActualHeight; double height = Math.Max(Math.Min(contentSettings.Size.Height, (totalHeight - splitter.Height) / 2), (totalHeight - splitter.Height) / 5); double ratioNew = height / totalHeight; double ratioOld = (totalHeight - height - splitter.Height) / totalHeight; if (dockTo == DockTo.Top) { RowDefinition topRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioNew, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinition bottomRow = NewRowDefinition(new GridLength(oldRow.Height.Value *ratioOld, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinitions[index * 2] = topRow; RowDefinitions.Insert(index * 2 + 1, bottomRow); RowDefinitions.Insert(index * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index, newChild); Children.Insert(index * 2, splitter); Children.Insert(index * 2, newChild); } else { RowDefinition topRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioOld, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinition bottomRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioNew, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinitions[index * 2] = topRow; RowDefinitions.Insert(index * 2 + 1, bottomRow); RowDefinitions.Insert(index * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index + 1, newChild); Children.Insert(index * 2 + 1, newChild); Children.Insert(index * 2 + 1, splitter); } for (int i = index * 2; i < Children.Count; i++) { Grid.SetRow(Children[i], i); } } } } else if (dockTo == DockTo.Left || dockTo == DockTo.Right || dockTo == DockTo.Top || dockTo == DockTo.Bottom) { DockedWindow dockedWindow = (DockedWindow)targetChild; int index = m_children.IndexOf(targetChild); GridLayout gridLayout = new GridLayout(Root); gridLayout.SetValue(Grid.ColumnProperty, dockedWindow.GetValue(Grid.ColumnProperty)); gridLayout.SetValue(Grid.RowProperty, dockedWindow.GetValue(Grid.RowProperty)); Children.Remove(dockedWindow); IDockContent content = dockedWindow.DockedContent; dockedWindow.Undock(content); m_children[index] = gridLayout; Children.Insert(index * 2, gridLayout); gridLayout.Dock(null, content, DockTo.Center); UpdateLayout(); gridLayout.Dock(content, newContent, dockTo); } else if (targetChild != null) { targetChild.Dock(nextTo, newContent, dockTo); } }
/// <summary> /// Read the layout from XML file and apply it to dockpanel</summary> /// <param name="reader">Source XML file</param> public void ApplyLayout(XmlReader reader) { try { if (reader == null) { PerformDefaultLayout(); } else { if (!m_templateApplied) { CacheLayout(reader); return; } if (m_layoutApplied) { ((IDockLayout)this).Close(); } if (reader.ReadToFollowing(this.GetType().Name, this.GetType().Namespace)) { reader.ReadStartElement(); if (reader.LocalName == "Contents") { if (reader.ReadToDescendant("Content")) { do { String ucid = reader.GetAttribute("UCID"); DockContent content = GetContent(ucid); if (content != null) { content.Settings.DockState = (DockState)Enum.Parse(typeof(DockState), reader.GetAttribute(typeof(DockState).Name)); try { var str = reader.GetAttribute("Location"); content.Settings.Location = Point.Parse(str); } catch (FormatException) { } try { var str = reader.GetAttribute("Size"); content.Settings.Size = Size.Parse(str); } catch (FormatException) { } } } while (reader.ReadToNextSibling("Content")); // there will only be an end element if "Content" entries were listed reader.ReadEndElement(); } else { if (reader.IsEmptyElement) { reader.Read(); } } // else, the "Contents" element was self-contained, and there is no end element to parse } if (reader.LocalName == typeof(GridLayout).Name) { GridLayout gridLayout = new GridLayout(this, reader.ReadSubtree()); GridLayout = gridLayout.Layouts.Count > 0 ? gridLayout : null; reader.ReadEndElement(); } if (reader.LocalName == typeof(FloatingWindow).Name) { do { FloatingWindow window = new FloatingWindow(this, reader.ReadSubtree()); if (window.DockedContent.Children.Count > 0) { window.Closing += ChildWindowClosing; m_windows.Add(window); window.Owner = Window.GetWindow(this); window.Show(); window.Left = window.Left; window.Top = window.Top; } else { // To-do: create "dummy content" like in DockPanelSuite, so that if the // window were to be created later, we could apply the layout. For now, // just set the owner. This ties the FloatingWindow to the main window, and // allows the app to shut down properly with the default Application.ShutdownMode // of OnLastWindowClose. window.Owner = Window.GetWindow(this); } } while (reader.ReadToNextSibling(typeof(FloatingWindow).Name)); reader.ReadEndElement(); } if (reader.LocalName == typeof(SidePopup).Name) { do { Dock dockSide = (Dock)Enum.Parse(typeof(Dock), reader.GetAttribute("Side")); switch (dockSide) { case System.Windows.Controls.Dock.Left: PART_LeftCollapsePanel.ReadXml(reader.ReadSubtree()); break; case System.Windows.Controls.Dock.Top: PART_TopCollapsePanel.ReadXml(reader.ReadSubtree()); break; case System.Windows.Controls.Dock.Right: PART_RightCollapsePanel.ReadXml(reader.ReadSubtree()); break; case System.Windows.Controls.Dock.Bottom: PART_BottomCollapsePanel.ReadXml(reader.ReadSubtree()); break; } } while (reader.ReadToNextSibling(typeof(SidePopup).Name)); reader.ReadEndElement(); } m_layoutApplied = true; } } } catch (Exception ex) { ((IDockLayout)this).Close(); PerformDefaultLayout(); throw ex; } }
/// <summary> /// Dock the new content next to content</summary> /// <param name="nextTo">Dock content to add new content next to</param> /// <param name="newContent">New content to be docked</param> /// <param name="dockTo">Side of nextTo content where new content should be docked</param> void IDockLayout.Dock(IDockContent nextTo, IDockContent newContent, DockTo dockTo) { if (GridLayout == null) { GridLayout = new GridLayout(this); GridLayout.Dock(null, newContent, DockTo.Center); } else { if (nextTo == null) { if (GridLayout.Children.Count < 2) { GridLayout.Dock(null, newContent, dockTo); } else { if (dockTo == DockTo.Center) { dockTo = DockTo.Right; } GridLayout gridLayout = GridLayout; GridLayout = null; gridLayout = new GridLayout(this, gridLayout); GridLayout = gridLayout; gridLayout.Dock(null, newContent, dockTo); } } else { GridLayout.Dock(nextTo, newContent, dockTo); } CheckConsistency(); } }
public void ReadXml(System.Xml.XmlReader reader) { if (reader.ReadToFollowing(this.GetType().Name)) { String s = reader.GetAttribute(Orientation.GetType().Name); m_orientation = (Orientation)(Enum.Parse(Orientation.GetType(), s)); switch (m_orientation) { case Orientation.Horizontal: if (reader.ReadToDescendant("Column")) { RowDefinitions.Add(NewRowDefinition(new GridLength(1, GridUnitType.Star), m_minGridSize.Height)); do { double width = double.Parse(reader.GetAttribute("Width"), CultureInfo.InvariantCulture); IDockLayout layout = null; reader.ReadStartElement(); if (reader.LocalName == typeof(DockedWindow).Name) { DockedWindow dockedWindow = new DockedWindow(Root, reader.ReadSubtree()); layout = dockedWindow.DockedContent.Children.Count != 0 ? dockedWindow : null; reader.ReadEndElement(); } else if (reader.LocalName == typeof(GridLayout).Name) { GridLayout gridLayout = new GridLayout(Root, reader.ReadSubtree()); layout = gridLayout.Layouts.Count > 0 ? gridLayout : null; reader.ReadEndElement(); } if (layout != null) { if (Children.Count > 0) { ColumnDefinitions.Add(NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Add(NewGridSplitter(Orientation)); } ColumnDefinitions.Add(NewColumnDefinition(new GridLength(width, GridUnitType.Star), m_minGridSize.Width)); m_children.Add(layout); Children.Add((FrameworkElement)layout); } } while (reader.ReadToNextSibling("Column")); } break; case Orientation.Vertical: if (reader.ReadToDescendant("Row")) { ColumnDefinitions.Add(NewColumnDefinition(new GridLength(1, GridUnitType.Star), m_minGridSize.Width)); do { double height = double.Parse(reader.GetAttribute("Height"), CultureInfo.InvariantCulture); IDockLayout layout = null; reader.ReadStartElement(); if (reader.LocalName == typeof(DockedWindow).Name) { DockedWindow dockedWindow = new DockedWindow(Root, reader.ReadSubtree()); layout = dockedWindow.DockedContent.Children.Count != 0 ? dockedWindow : null; reader.ReadEndElement(); } else if (reader.LocalName == typeof(GridLayout).Name) { GridLayout gridLayout = new GridLayout(Root, reader.ReadSubtree()); layout = gridLayout.Layouts.Count > 0 ? gridLayout : null; reader.ReadEndElement(); } if (layout != null) { if (Children.Count > 0) { RowDefinitions.Add(NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Add(NewGridSplitter(Orientation)); } RowDefinitions.Add(NewRowDefinition(new GridLength(height, GridUnitType.Star), m_minGridSize.Height)); m_children.Add(layout); Children.Add((FrameworkElement)layout); } } while (reader.ReadToNextSibling("Row")); } break; } for (int i = 0; i < Children.Count; i++) { Grid.SetColumn(Children[i], Orientation == Orientation.Horizontal ? i : 0); Grid.SetRow(Children[i], Orientation == Orientation.Vertical ? i : 0); } reader.ReadEndElement(); } }
public void Dock(IDockContent nextTo, IDockContent newContent, DockTo dockTo) { IDockLayout targetChild = null; if (nextTo != null) { foreach (IDockLayout child in m_children) { if (child.HasChild(nextTo)) { targetChild = child; break; } } } if (targetChild == null) { foreach (IDockLayout child in m_children) { if (child.HasDescendant(nextTo)) { child.Dock(nextTo, newContent, dockTo); // child was docked, nothing else is necessary return; } } } if (dockTo == DockTo.Center && m_children.Count == 1) { m_children[0].Dock(null, newContent, dockTo); } else if (m_children.Count < 2) { if (dockTo == DockTo.Center) { dockTo = DockTo.Right; } if (dockTo == DockTo.Top || dockTo == DockTo.Bottom) { m_orientation = Orientation.Vertical; } else { m_orientation = Orientation.Horizontal; } DockedWindow newChild = new DockedWindow(Root, newContent); if (Children.Count == 0) { AddFirstChild(newChild); } else { if (targetChild == null) { if (dockTo == DockTo.Top || dockTo == DockTo.Left) { targetChild = m_children[0]; } else { targetChild = m_children[m_children.Count - 1]; } } FrameworkElement control = (FrameworkElement)targetChild; int index = m_children.IndexOf(targetChild); if (dockTo == DockTo.Left || dockTo == DockTo.Right) { GridSplitter splitter = NewGridSplitter(Orientation.Horizontal); int column = (int)control.GetValue(Grid.ColumnProperty); ColumnDefinition oldColumn = ColumnDefinitions[index * 2]; ContentSettings contentSettings = (newContent is TabLayout) ? ((TabLayout)newContent).Children[0].Settings : ((DockContent)newContent).Settings; double totalWidth = ((FrameworkElement)targetChild).ActualWidth; double width = Math.Max(Math.Min(contentSettings.Size.Width, (totalWidth - splitter.Width) / 2), (totalWidth - splitter.Width) / 5); double ratioNew = width / totalWidth; double ratioOld = (totalWidth - width - splitter.Width) / totalWidth; if (dockTo == DockTo.Left) { ColumnDefinition leftColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioNew, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinition rightColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioOld, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinitions[index * 2] = leftColumn; ColumnDefinitions.Insert(index * 2 + 1, rightColumn); ColumnDefinitions.Insert(index * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index, newChild); Children.Insert(index * 2, splitter); Children.Insert(index * 2, newChild); } else { ColumnDefinition leftColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioOld, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinition rightColumn = NewColumnDefinition(new GridLength(oldColumn.Width.Value * ratioNew, oldColumn.Width.GridUnitType), m_minGridSize.Width); ColumnDefinitions[index * 2] = leftColumn; ColumnDefinitions.Insert(index * 2 + 1, rightColumn); ColumnDefinitions.Insert(index * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index + 1, newChild); Children.Insert(index * 2 + 1, newChild); Children.Insert(index * 2 + 1, splitter); } for (int i = index * 2; i < Children.Count; i++) { Grid.SetColumn(Children[i], i); } } else { GridSplitter splitter = NewGridSplitter(Orientation.Vertical); int row = (int)control.GetValue(Grid.RowProperty); RowDefinition oldRow = RowDefinitions[index * 2]; ContentSettings contentSettings = (newContent is TabLayout) ? ((TabLayout)newContent).Children[0].Settings : ((DockContent)newContent).Settings; double totalHeight = ((FrameworkElement)targetChild).ActualHeight; double height = Math.Max(Math.Min(contentSettings.Size.Height, (totalHeight - splitter.Height) / 2), (totalHeight - splitter.Height) / 5); double ratioNew = height / totalHeight; double ratioOld = (totalHeight - height - splitter.Height) / totalHeight; if (dockTo == DockTo.Top) { RowDefinition topRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioNew, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinition bottomRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioOld, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinitions[index * 2] = topRow; RowDefinitions.Insert(index * 2 + 1, bottomRow); RowDefinitions.Insert(index * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index, newChild); Children.Insert(index * 2, splitter); Children.Insert(index * 2, newChild); } else { RowDefinition topRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioOld, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinition bottomRow = NewRowDefinition(new GridLength(oldRow.Height.Value * ratioNew, oldRow.Height.GridUnitType), m_minGridSize.Height); RowDefinitions[index * 2] = topRow; RowDefinitions.Insert(index * 2 + 1, bottomRow); RowDefinitions.Insert(index * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); m_children.Insert(index + 1, newChild); Children.Insert(index * 2 + 1, newChild); Children.Insert(index * 2 + 1, splitter); } for (int i = index * 2; i < Children.Count; i++) { Grid.SetRow(Children[i], i); } } } } else if (dockTo == DockTo.Left || dockTo == DockTo.Right || dockTo == DockTo.Top || dockTo == DockTo.Bottom) { DockedWindow dockedWindow = (DockedWindow)targetChild; int index = m_children.IndexOf(targetChild); GridLayout gridLayout = new GridLayout(Root); gridLayout.SetValue(Grid.ColumnProperty, dockedWindow.GetValue(Grid.ColumnProperty)); gridLayout.SetValue(Grid.RowProperty, dockedWindow.GetValue(Grid.RowProperty)); Children.Remove(dockedWindow); IDockContent content = dockedWindow.DockedContent; dockedWindow.Undock(content); m_children[index] = gridLayout; Children.Insert(index * 2, gridLayout); gridLayout.Dock(null, content, DockTo.Center); UpdateLayout(); gridLayout.Dock(content, newContent, dockTo); } else if (targetChild != null) { targetChild.Dock(nextTo, newContent, dockTo); } }
/// <summary> /// Will merge itself with given grid. Basicly it takes child grid, removes that grid, and all /// children of removed grid will be added to this grid. The child grid must have same orientation /// or maximum of 1 child. /// </summary> /// <param name="grid">Grid to merge with</param> internal void MergeWith(GridLayout grid) { // get the index of the grid to merge with (it is child of this grid) int index = m_children.IndexOf(grid); double totalValue = 0; int indexOffset = 0; if (Orientation == Orientation.Horizontal) { // get the column definition of child grid ColumnDefinition oldColumnDef = ColumnDefinitions[index * 2]; // count the sum of columns widths of childs children foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int columnIndex = Grid.GetColumn(element); ColumnDefinition layoutColumnDef = grid.ColumnDefinitions[columnIndex]; totalValue += layoutColumnDef.Width.Value; } // remove the child from our list, from view children adn from column definitions m_children.RemoveAt(index); Children.RemoveAt(index * 2); ColumnDefinitions.RemoveAt(index * 2); // move all childs children to this grid and create column definitions for each of them foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int columnIndex = Grid.GetColumn(element); ColumnDefinition layoutColumnDef = grid.ColumnDefinitions[columnIndex]; double newValue = oldColumnDef.Width.Value * layoutColumnDef.Width.Value / totalValue; ColumnDefinition newColumnDef = NewColumnDefinition(new GridLength(newValue, GridUnitType.Star), m_minGridSize.Width); grid.Children.Remove(element); ColumnDefinitions.Insert((index + indexOffset) * 2, newColumnDef); Children.Insert((index + indexOffset) * 2, element); m_children.Insert(index + indexOffset, newLayout); if (indexOffset < grid.Layouts.Count - 1) { // if we move more than one child, then we need to add new splitters too GridSplitter splitter = NewGridSplitter(Orientation.Horizontal); ColumnDefinitions.Insert((index + indexOffset) * 2 + 1, NewColumnDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Insert((index + indexOffset) * 2 + 1, splitter); } indexOffset++; } // set the association of column indexes for (int i = 0; i < Children.Count; i++) { Grid.SetColumn(Children[i], i); } } else { // get the row definition of child grid RowDefinition oldRowDef = RowDefinitions[index * 2]; // count the sum of row heights of childs children foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int RowIndex = Grid.GetRow(element); RowDefinition layoutRowDef = grid.RowDefinitions[RowIndex]; totalValue += layoutRowDef.Height.Value; } // remove the child from our list, from view children adn from row definitions m_children.RemoveAt(index); Children.RemoveAt(index * 2); RowDefinitions.RemoveAt(index * 2); // move all childs children to this grid and create row definitions for each of them foreach (IDockLayout newLayout in grid.Layouts) { FrameworkElement element = (FrameworkElement)newLayout; int RowIndex = Grid.GetRow(element); RowDefinition layoutRowDef = grid.RowDefinitions[RowIndex]; double newValue = oldRowDef.Height.Value * layoutRowDef.Height.Value / totalValue; RowDefinition newRowDef = NewRowDefinition(new GridLength(newValue, GridUnitType.Star), m_minGridSize.Height); grid.Children.Remove(element); RowDefinitions.Insert((index + indexOffset) * 2, newRowDef); Children.Insert((index + indexOffset) * 2, element); m_children.Insert(index + indexOffset, newLayout); if (indexOffset < grid.Layouts.Count - 1) { // if we move more than one child, then we need to add new splitters too GridSplitter splitter = NewGridSplitter(Orientation.Vertical); RowDefinitions.Insert((index + indexOffset) * 2 + 1, NewRowDefinition(new GridLength(1, GridUnitType.Auto), 0)); Children.Insert((index + indexOffset) * 2 + 1, splitter); } indexOffset++; } // set the association of row indexes for (int i = 0; i < Children.Count; i++) { Grid.SetRow(Children[i], i); } } }