internal void AddDockControl(IDockControl ctrl) { if (!_dockControls.ContainsKey(ctrl.ID)) { _dockControls.Add(ctrl.ID, ctrl); } }
internal void RemoveDockControl(IDockControl ctrl) { if (_dockControls.ContainsKey(ctrl.ID)) { _dockControls.Remove(ctrl.ID); } }
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); }
public WorldView(DockManager dockManager, IDockControl navigateDockControl, Action <Scross> setScross, EditMode editMode) { _setScross = setScross; _editMode = editMode; _dockManager = dockManager; NavigateDockControl = navigateDockControl; InitializeComponent(); DataContext = this; }
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)); } }
internal void RemoveDockControl(IDockControl ctrl) { if (_dockControls.ContainsKey(ctrl.ID)) { _dockControls.Remove(ctrl.ID); if (ctrl.ID >= _fixCount) { _disposedID.Push(ctrl.ID); } } }
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(); }
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); }
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)); } }
/// <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!"); } }
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); }
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); }
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); } }
/// <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)); }
/// <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); }
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); }
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(); } }
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(); }
/// <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!"); } }
public static XElement Save(IDockControl dockControl) { return Save(dockControl, false); }
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; }
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); }
public static XElement Save(IDockControl dockControl) { return(Save(dockControl, false)); }
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(); } }
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); }
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); }