private void _AttachWithSplit(IDockView child, AttachMode mode, int index) { if (child is LayoutDocumentGroupControl) { if (Direction == Direction.None) { Direction = (mode == AttachMode.Left_WithSplit || mode == AttachMode.Right_WithSplit) ? Direction.LeftToRight : Direction.UpToDown; } _AttachChild(child, index); if (DockViewParent != null) { DockManager.Root.DocumentModels.Add(child.Model as BaseLayoutGroup); } } if (child is AnchorSideGroupControl) { var model = (child as AnchorSideGroupControl).Model as LayoutGroup; var _children = new List <IDockElement>(model.Children); model.Dispose(); var group = new LayoutDocumentGroup(DockViewParent == null ? DockMode.Float : DockMode.Normal, DockManager); foreach (var _child in _children) { group.Attach(_child); } var ctrl = new LayoutDocumentGroupControl(group); _AttachChild(ctrl, index); (child as IDisposable).Dispose(); } if (child is LayoutGroupDocumentPanel || child is LayoutGroupPanel) { var _children = new List <IDockView>((child as LayoutGroupPanel).Children.OfType <IDockView>()); _children.Reverse(); (child as LayoutGroupPanel).Children.Clear(); foreach (var _child in _children) { _AttachWithSplit(_child as IDockView, mode, index); } (child as IDisposable).Dispose(); } //if (child is IDisposable) // (child as IDisposable).Dispose(); }
/// <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!"); } }
/// <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!"); } }
private void _InitDragItem() { LayoutGroup group; IDockElement ele; var mouseP = DockHelper.GetMousePosition(DockManager); switch (_dragItem.DockMode) { case DockMode.Normal: if (_dragItem.RelativeObj is ILayoutGroup) { var _layoutGroup = _dragItem.RelativeObj as LayoutGroup; #region AttachObj var _parent = _layoutGroup.View.DockViewParent as LayoutGroupPanel; var _mode = _parent.Direction == Direction.Horizontal ? AttachMode.Left : AttachMode.Top; if (_parent.Direction == Direction.None) { _mode = AttachMode.None; } var _index = _parent.IndexOf(_layoutGroup.View); if (_parent.Children.Count - 1 > _index) { _layoutGroup.AttachObj = new AttachObject(_layoutGroup, _parent.Children[_index + 2] as INotifyDisposable, _index, _mode); } else { _layoutGroup.AttachObj = new AttachObject(_layoutGroup, _parent.Children[_index - 2] as INotifyDisposable, _index, _mode); } #endregion //这里移动的一定是AnchorSideGroup,故将其从父级LayoutGroupPanel移走,但不Dispose留着构造浮动窗口 if ((_layoutGroup.View as ILayoutGroupControl).TryDeatchFromParent(false)) { //注意重新设置Mode (_layoutGroup as BaseLayoutGroup).Mode = DockMode.Float; _dragWnd = new AnchorGroupWindow(DockManager) { Left = mouseP.X - _dragItem.ClickPos.X - 1, Top = mouseP.Y - _dragItem.ClickPos.Y - 1 }; _dragWnd.AttachChild(_layoutGroup.View, AttachMode.None, 0); _dragWnd.Show(); } } else if (_dragItem.RelativeObj is IDockElement) { ele = _dragItem.RelativeObj as IDockElement; #region AttachObj var _parent = (ele.Container as LayoutGroup).View as BaseGroupControl; var _index = ele.Container.IndexOf(ele); #endregion if (ele.IsDocument) { group = new LayoutDocumentGroup(DockMode.Float, DockManager); } else { group = new LayoutGroup(ele.Side, DockMode.Float, DockManager); group.AttachObj = new AttachObject(group, _parent, _index); } //先从逻辑父级中移除 ele.Container.Detach(ele); //再加入新的逻辑父级 group.Attach(ele); //创建新的浮动窗口,并初始化位置 if (ele.IsDocument) { _dragWnd = new DocumentGroupWindow(DockManager); _dragWnd.AttachChild(new LayoutDocumentGroupControl(group), AttachMode.None, 0); _dragWnd.Top = mouseP.Y - _dragItem.ClickPos.Y; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - _dragItem.ClickRect.Left - Constants.DocumentWindowPadding; } else { _dragWnd = new AnchorGroupWindow(DockManager) { NeedReCreate = _dragItem.DragMode == DragMode.Anchor }; _dragWnd.AttachChild(new AnchorSideGroupControl(group) { IsDraggingFromDock = _dragItem.DragMode == DragMode.Anchor }, AttachMode.None, 0); if (!_dragWnd.NeedReCreate) { _dragWnd.Top = mouseP.Y - _dragItem.ClickPos.Y; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - _dragItem.ClickRect.Left - Constants.DocumentWindowPadding; } else { _dragWnd.Top = mouseP.Y + _dragItem.ClickPos.Y - _dragWnd.Height; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - Constants.DocumentWindowPadding; } } if (_dragWnd is DocumentGroupWindow) { _dragWnd.Recreate(); } _dragWnd.Show(); } break; case DockMode.DockBar: //这里表示从自动隐藏窗口进行的拖动,因此这里移除自动隐藏窗口 ele = _dragItem.RelativeObj as IDockElement; ele.Container.Detach(ele); //创建新的浮动窗口,并初始化位置 group = new LayoutGroup(ele.Side, DockMode.Float, DockManager); group.Attach(ele); _dragWnd = new AnchorGroupWindow(DockManager) { Left = mouseP.X - _dragItem.ClickPos.X - 1, Top = mouseP.Y - _dragItem.ClickPos.Y - 1 }; _dragWnd.AttachChild(new AnchorSideGroupControl(group), AttachMode.None, 0); _dragWnd.Show(); break; case DockMode.Float: if (_dragItem.RelativeObj is IDockElement) { ele = _dragItem.RelativeObj as IDockElement; var ctrl = ele.Container.View as BaseGroupControl; if (ctrl.Items.Count == 1 && ctrl.Parent is BaseFloatWindow) { _dragWnd = ctrl.Parent as BaseFloatWindow; _dragWnd.DetachChild(ctrl); _dragWnd.Close(); _dragWnd = new DocumentGroupWindow(DockManager); _dragWnd.AttachChild(ctrl, AttachMode.None, 0); _dragWnd.Top = mouseP.Y - _dragItem.ClickPos.Y; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - _dragItem.ClickRect.Left - Constants.DocumentWindowPadding; _dragWnd.Recreate(); _dragWnd.Show(); } else { #region AttachObj var _parent = (ele.Container as LayoutGroup).View as BaseGroupControl; var _index = ele.Container.IndexOf(ele); #endregion if (ele.IsDocument) { group = new LayoutDocumentGroup(DockMode.Float, DockManager); } else { group = new LayoutGroup(ele.Side, DockMode.Float, DockManager); group.AttachObj = new AttachObject(group, _parent, _index); } //先从逻辑父级中移除 ele.Container.Detach(ele); //再加入新的逻辑父级 group.Attach(ele); //创建新的浮动窗口,并初始化位置 //这里可知引起drag的时DragTabItem故这里创建临时的DragTabWindow if (ele.IsDocument) { _dragWnd = new DocumentGroupWindow(DockManager); _dragWnd.AttachChild(new LayoutDocumentGroupControl(group), AttachMode.None, 0); _dragWnd.Top = mouseP.Y - _dragItem.ClickPos.Y; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - _dragItem.ClickRect.Left - Constants.DocumentWindowPadding; } else { _dragWnd = new AnchorGroupWindow(DockManager) { NeedReCreate = _dragItem.DragMode == DragMode.Anchor }; _dragWnd.AttachChild(new AnchorSideGroupControl(group) { IsDraggingFromDock = _dragItem.DragMode == DragMode.Anchor }, AttachMode.None, 0); if (!_dragWnd.NeedReCreate) { _dragWnd.Top = mouseP.Y - _dragItem.ClickPos.Y; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - _dragItem.ClickRect.Left - Constants.DocumentWindowPadding; } else { _dragWnd.Top = mouseP.Y + _dragItem.ClickPos.Y - _dragWnd.Height; _dragWnd.Left = mouseP.X - _dragItem.ClickPos.X - Constants.DocumentWindowPadding; } } if (_dragWnd is DocumentGroupWindow) { _dragWnd.Recreate(); } _dragWnd.Show(); } } else if (_dragItem.RelativeObj is ILayoutGroup) { group = _dragItem.RelativeObj as LayoutGroup; //表示此时的浮动窗口为IsSingleMode if (group.View.DockViewParent == null) { _dragWnd = (group.View as BaseGroupControl).Parent as BaseFloatWindow; } else { #region AttachObj var _parent = group.View.DockViewParent as LayoutGroupPanel; var _mode = _parent.Direction == Direction.Horizontal ? AttachMode.Left : AttachMode.Top; if (_parent.Direction == Direction.None) { _mode = AttachMode.None; } var _index = _parent.IndexOf(group.View); if (_parent.Children.Count - 1 > _index) { group.AttachObj = new AttachObject(group, _parent.Children[_index + 2] as INotifyDisposable, _index, _mode); } else { group.AttachObj = new AttachObject(group, _parent.Children[_index - 2] as INotifyDisposable, _index, _mode); } #endregion //这里移动的一定是AnchorSideGroup,故将其从父级LayoutGroupPanel移走,但不Dispose留着构造浮动窗口 if ((group.View as ILayoutGroupControl).TryDeatchFromParent(false)) { _dragWnd = new AnchorGroupWindow(DockManager) { Left = mouseP.X - _dragItem.ClickPos.X - 1, Top = mouseP.Y - _dragItem.ClickPos.Y - 1 }; _dragWnd.AttachChild(group.View, AttachMode.None, 0); _dragWnd.Show(); } } } break; } }