From b49f1d08048bede7a24eb84795cad31ff529fdde Mon Sep 17 00:00:00 2001 From: John Stewien Date: Thu, 22 Dec 2022 14:33:29 +1030 Subject: [PATCH 1/3] Added event notifications for when an Anchorable is being hidden or closed. --- .../AvalonDock/AnchorableClosedEventArgs.cs | 35 +++++++++++++++ .../AvalonDock/AnchorableClosingEventArgs.cs | 35 +++++++++++++++ .../AvalonDock/AnchorableHiddenEventArgs.cs | 35 +++++++++++++++ .../AvalonDock/AnchorableHidingEventArgs.cs | 40 +++++++++++++++++ .../Components/AvalonDock/DockingManager.cs | 45 +++++++++++++++++-- .../AvalonDock/Layout/LayoutAnchorable.cs | 5 ++- 6 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 source/Components/AvalonDock/AnchorableClosedEventArgs.cs create mode 100644 source/Components/AvalonDock/AnchorableClosingEventArgs.cs create mode 100644 source/Components/AvalonDock/AnchorableHiddenEventArgs.cs create mode 100644 source/Components/AvalonDock/AnchorableHidingEventArgs.cs diff --git a/source/Components/AvalonDock/AnchorableClosedEventArgs.cs b/source/Components/AvalonDock/AnchorableClosedEventArgs.cs new file mode 100644 index 00000000..eb24cef0 --- /dev/null +++ b/source/Components/AvalonDock/AnchorableClosedEventArgs.cs @@ -0,0 +1,35 @@ +/************************************************************************ + AvalonDock + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at https://opensource.org/licenses/MS-PL + ************************************************************************/ + +using AvalonDock.Layout; +using System; + +namespace AvalonDock +{ + /// + /// Implements an event that can be raised to inform the client application about an + /// anchorable that been closed and removed its content (viewmodel) from the docking framework. + /// + public class AnchorableClosedEventArgs : EventArgs + { + /// + /// Class constructor from the anchorables layout model. + /// + /// + public AnchorableClosedEventArgs(LayoutAnchorable anchorable) + { + Anchorable = anchorable; + } + + /// + /// Gets the model of the anchorable that has been closed. + /// + public LayoutAnchorable Anchorable { get; private set; } + } +} \ No newline at end of file diff --git a/source/Components/AvalonDock/AnchorableClosingEventArgs.cs b/source/Components/AvalonDock/AnchorableClosingEventArgs.cs new file mode 100644 index 00000000..4f29a4d3 --- /dev/null +++ b/source/Components/AvalonDock/AnchorableClosingEventArgs.cs @@ -0,0 +1,35 @@ +/************************************************************************ + AvalonDock + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at https://opensource.org/licenses/MS-PL + ************************************************************************/ + +using AvalonDock.Layout; +using System.ComponentModel; + +namespace AvalonDock +{ + /// + /// Implements a Cancelable event that can be raised to ask the client application whether closing this anchorable + /// and removing its content (viewmodel) is OK or not. + /// + public class AnchorableClosingEventArgs : CancelEventArgs + { + /// + /// Class constructor from the anchorable layout model. + /// + /// + public AnchorableClosingEventArgs(LayoutAnchorable anchorable) + { + Anchorable = anchorable; + } + + /// + /// Gets the model of the anchorable that is about to be closed. + /// + public LayoutAnchorable Anchorable { get; private set; } + } +} \ No newline at end of file diff --git a/source/Components/AvalonDock/AnchorableHiddenEventArgs.cs b/source/Components/AvalonDock/AnchorableHiddenEventArgs.cs new file mode 100644 index 00000000..f595612e --- /dev/null +++ b/source/Components/AvalonDock/AnchorableHiddenEventArgs.cs @@ -0,0 +1,35 @@ +/************************************************************************ + AvalonDock + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at https://opensource.org/licenses/MS-PL + ************************************************************************/ + +using AvalonDock.Layout; +using System; + +namespace AvalonDock +{ + /// + /// Implements an event that can be raised to inform the client application about an + /// anchorable that been hidden. + /// + public class AnchorableHiddenEventArgs : EventArgs + { + /// + /// Class constructor from the anchorables layout model. + /// + /// + public AnchorableHiddenEventArgs(LayoutAnchorable anchorable) + { + Anchorable = anchorable; + } + + /// + /// Gets the model of the anchorable that has been hidden. + /// + public LayoutAnchorable Anchorable { get; private set; } + } +} \ No newline at end of file diff --git a/source/Components/AvalonDock/AnchorableHidingEventArgs.cs b/source/Components/AvalonDock/AnchorableHidingEventArgs.cs new file mode 100644 index 00000000..2367199f --- /dev/null +++ b/source/Components/AvalonDock/AnchorableHidingEventArgs.cs @@ -0,0 +1,40 @@ +/************************************************************************ + AvalonDock + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at https://opensource.org/licenses/MS-PL + ************************************************************************/ + +using AvalonDock.Layout; +using System.ComponentModel; + +namespace AvalonDock +{ + /// + /// Implements a Cancelable event that can be raised to ask the client application whether hiding this anchorable + /// is OK or not. + /// + public class AnchorableHidingEventArgs : CancelEventArgs + { + /// + /// Class constructor from the anchorable layout model. + /// + /// + public AnchorableHidingEventArgs(LayoutAnchorable anchorable) + { + Anchorable = anchorable; + } + + /// + /// Gets the model of the anchorable that is about to be hidden. + /// + public LayoutAnchorable Anchorable { get; private set; } + + /// + /// Gets or sets a value indicating whether an anchorable should be closed instead of hidden + /// + public bool CloseInsteadOfHide { get; set; } + } +} \ No newline at end of file diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index 762917bc..6a73991f 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -115,6 +115,20 @@ public DockingManager() /// Event fired after a document is closed. public event EventHandler DocumentClosed; + /// Event fired when an anchorable is about to be closed. + /// Subscribers have the opportuniy to cancel the operation. + public event EventHandler AnchorableClosing; + + /// Event fired after an anchorable is closed + public event EventHandler AnchorableClosed; + + /// Event fired when an anchorable is about to be hidden. + /// Subscribers have the opportuniy to cancel the operation. + public event EventHandler AnchorableHiding; + + /// Event fired after an anchorable is hidden + public event EventHandler AnchorableHidden; + /// Event is raised when changes. /// public event EventHandler ActiveContentChanged; @@ -1922,11 +1936,36 @@ internal void ExecuteCloseAllCommand(LayoutContent contentSelected) internal void ExecuteCloseCommand(LayoutAnchorable anchorable) { if (!(anchorable is LayoutAnchorable model)) return; - model.CloseAnchorable(); - RemoveViewFromLogicalChild(anchorable); + + AnchorableClosingEventArgs closingArgs = null; + AnchorableClosing?.Invoke(this, closingArgs = new AnchorableClosingEventArgs(model)); + if (closingArgs?.Cancel == true) + return; + + if (model.CloseAnchorable()) + { + RemoveViewFromLogicalChild(model); + AnchorableClosed?.Invoke(this, new AnchorableClosedEventArgs(model)); + } } - internal void ExecuteHideCommand(LayoutAnchorable anchorable) => anchorable?.Hide(); + internal void ExecuteHideCommand(LayoutAnchorable anchorable) + { + if (!(anchorable is LayoutAnchorable model)) return; + + AnchorableHidingEventArgs hidingArgs = null; + AnchorableHiding?.Invoke(this, hidingArgs = new AnchorableHidingEventArgs(model)); + if (hidingArgs?.CloseInsteadOfHide == true) + { + ExecuteCloseCommand(model); + return; + } + if (hidingArgs?.Cancel == true) return; + + model.Hide(); + + AnchorableHidden?.Invoke(this, new AnchorableHiddenEventArgs(model)); + } internal void ExecuteAutoHideCommand(LayoutAnchorable _anchorable) => _anchorable.ToggleAutoHide(); diff --git a/source/Components/AvalonDock/Layout/LayoutAnchorable.cs b/source/Components/AvalonDock/Layout/LayoutAnchorable.cs index c098d113..4adda820 100644 --- a/source/Components/AvalonDock/Layout/LayoutAnchorable.cs +++ b/source/Components/AvalonDock/Layout/LayoutAnchorable.cs @@ -608,11 +608,12 @@ public void ToggleAutoHide() #region Internal Methods - internal void CloseAnchorable() + internal bool CloseAnchorable() { - if (!TestCanClose()) return; + if (!TestCanClose()) return false; if (IsAutoHidden) ToggleAutoHide(); CloseInternal(); + return true; } // BD: 17.08.2020 Remove that bodge and handle CanClose=false && CanHide=true in XAML From 49e7b3d146481f5b71453e8fbc96081cdfd43bde Mon Sep 17 00:00:00 2001 From: John Stewien Date: Thu, 22 Dec 2022 16:11:37 +1030 Subject: [PATCH 2/3] Added unit tests for Anchorable Hiding and Closing events --- .../AvalonDockTest/AnchorablePaneTest.cs | 230 +++++++++++++++++- 1 file changed, 229 insertions(+), 1 deletion(-) diff --git a/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs b/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs index 3f461d2f..e1eb1540 100644 --- a/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs +++ b/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs @@ -1,4 +1,4 @@ -namespace AvalonDockTest +namespace AvalonDockTest { using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.STAExtensions; @@ -6,6 +6,10 @@ using AvalonDock.Layout; using AvalonDockTest.TestHelpers; using AvalonDockTest.views; + using AvalonDock; + using System.Collections.Generic; + using System.Linq; + using AvalonDock.Controls; [STATestClass] public class AnchorablePaneTest : AutomationTestBase @@ -30,5 +34,229 @@ public void AnchorablePaneHideCloseTest() ILayoutContainer actualContainer = windows.Screen3.Parent; Assert.AreEqual(expectedContainer, actualContainer); } + + [STATestMethod] + public void AnchorablePaneHideCloseEventsFiredTest() + { + // Create the window with 2 LayoutAnchorable items + + TestHost.SwitchToAppThread(); + + Task taskResult = WindowHelpers.CreateInvisibleWindowAsync(); + + taskResult.Wait(); + + AnchorablePaneTestWindow windows = taskResult.Result; + DockingManager dockingManager = windows.dockingManager; + + // These lists hold a record of the anchorable hide and close events + + List isHidingRaised = new List(); + List isHiddenRaised = new List(); + List isClosingRaised = new List(); + List isClosedRaised = new List(); + + // Event handlers for the hide and close events + + dockingManager.AnchorableClosing += (s, e) => isClosingRaised.Add(e.Anchorable); + dockingManager.AnchorableClosed += (s, e) => isClosedRaised.Add(e.Anchorable); + dockingManager.AnchorableHiding += (s, e) => isHidingRaised.Add(e.Anchorable); + dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); + + // Get the visual items + + LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; + LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; + + Assert.IsNotNull(item2); + Assert.IsNotNull(item3); + + // Ensure the items can be hidden and closed + + item2.CanClose = true; + item3.CanClose = true; + item2.CanHide = true; + item3.CanHide = true; + + // Hide item3 + + item3.HideCommand.Execute(null); + + // Ensure only item3 is hidden, and check the correct events were fired + + Assert.IsFalse(windows.Screen2.IsHidden); + Assert.IsTrue(windows.Screen3.IsHidden); + Assert.AreEqual(1, isHidingRaised.Count); + Assert.AreEqual(1, isHiddenRaised.Count); + Assert.AreEqual(0, isClosingRaised.Count); + Assert.AreEqual(0, isClosedRaised.Count); + + Assert.AreEqual(windows.Screen3, isHidingRaised.First()); + Assert.AreEqual(windows.Screen3, isHiddenRaised.First()); + + isHidingRaised.Clear(); + isHiddenRaised.Clear(); + + // Close item2 + + item2.CloseCommand.Execute(null); + + // Check the correct events were fired + + Assert.AreEqual(0, isHidingRaised.Count); + Assert.AreEqual(0, isHiddenRaised.Count); + Assert.AreEqual(1, isClosingRaised.Count); + Assert.AreEqual(1, isClosedRaised.Count); + + Assert.AreEqual(windows.Screen2, isClosingRaised.First()); + Assert.AreEqual(windows.Screen2, isClosedRaised.First()); + } + + [STATestMethod] + public void AnchorablePaneHideCloseEventsCancelledTest() + { + // Create the window with 2 LayoutAnchorable items + + TestHost.SwitchToAppThread(); + + Task taskResult = WindowHelpers.CreateInvisibleWindowAsync(); + + taskResult.Wait(); + + AnchorablePaneTestWindow windows = taskResult.Result; + DockingManager dockingManager = windows.dockingManager; + + // These lists hold a record of the anchorable hide and close events + + List isHidingRaised = new List(); + List isHiddenRaised = new List(); + List isClosingRaised = new List(); + List isClosedRaised = new List(); + + // Event handlers for the hide and close events + + dockingManager.AnchorableClosing += (s, e) => + { + e.Cancel = true; + isClosingRaised.Add(e.Anchorable); + }; + dockingManager.AnchorableClosed += (s, e) => isClosedRaised.Add(e.Anchorable); + dockingManager.AnchorableHiding += (s, e) => + { + e.Cancel = true; + isHidingRaised.Add(e.Anchorable); + }; + dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); + + // Get the visual items + + LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; + LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; + + Assert.IsNotNull(item2); + Assert.IsNotNull(item3); + + // Ensure the items can be hidden and closed + + item2.CanClose = true; + item3.CanClose = true; + item2.CanHide = true; + item3.CanHide = true; + + // Hide item3 + + item3.HideCommand.Execute(null); + + // Ensure nothing was hidden but cancelled instead, and check the correct events were fired + + Assert.IsFalse(windows.Screen2.IsHidden); + Assert.IsFalse(windows.Screen3.IsHidden); + Assert.AreEqual(1, isHidingRaised.Count); + Assert.AreEqual(0, isHiddenRaised.Count); + Assert.AreEqual(0, isClosingRaised.Count); + Assert.AreEqual(0, isClosedRaised.Count); + + Assert.AreEqual(windows.Screen3, isHidingRaised.First()); + + isHidingRaised.Clear(); + + // Close item2 + + item2.CloseCommand.Execute(null); + + // Ensure nothing was closed, and check the correct events were fired + + Assert.AreEqual(0, isHidingRaised.Count); + Assert.AreEqual(0, isHiddenRaised.Count); + Assert.AreEqual(1, isClosingRaised.Count); + Assert.AreEqual(0, isClosedRaised.Count); + + Assert.AreEqual(windows.Screen2, isClosingRaised.First()); + } + + [STATestMethod] + public void AnchorablePaneHideEventRedirectTest() + { + // Create the window with 2 LayoutAnchorable items + + TestHost.SwitchToAppThread(); + + Task taskResult = WindowHelpers.CreateInvisibleWindowAsync(); + + taskResult.Wait(); + + AnchorablePaneTestWindow windows = taskResult.Result; + DockingManager dockingManager = windows.dockingManager; + + // These lists hold a record of the anchorable hide and close events + + List isHidingRaised = new List(); + List isHiddenRaised = new List(); + List isClosingRaised = new List(); + List isClosedRaised = new List(); + + // Event handlers for the hide and close events + + dockingManager.AnchorableClosing += (s, e) => isClosingRaised.Add(e.Anchorable); + dockingManager.AnchorableClosed += (s, e) => isClosedRaised.Add(e.Anchorable); + dockingManager.AnchorableHiding += (s, e) => + { + e.CloseInsteadOfHide = true; + isHidingRaised.Add(e.Anchorable); + }; + dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); + + // Get the visual items + + LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; + LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; + + Assert.IsNotNull(item2); + Assert.IsNotNull(item3); + + // Ensure the items can be hidden and closed + + item2.CanClose = true; + item3.CanClose = true; + item2.CanHide = true; + item3.CanHide = true; + + // Hide item3 + + item3.HideCommand.Execute(null); + + // Ensure nothing was hidden but cancelled instead, and check the correct events were fired + + Assert.IsFalse(windows.Screen2.IsHidden); + Assert.IsFalse(windows.Screen3.IsHidden); + Assert.AreEqual(1, isHidingRaised.Count); + Assert.AreEqual(0, isHiddenRaised.Count); + Assert.AreEqual(1, isClosingRaised.Count); + Assert.AreEqual(1, isClosedRaised.Count); + + Assert.AreEqual(windows.Screen3, isHidingRaised.First()); + Assert.AreEqual(windows.Screen3, isClosingRaised.First()); + Assert.AreEqual(windows.Screen3, isClosedRaised.First()); + } } } From 2dd0af09afdd90e2bc53939fb1c6e267241a0ab1 Mon Sep 17 00:00:00 2001 From: John Stewien Date: Thu, 22 Dec 2022 17:52:57 +1030 Subject: [PATCH 3/3] Redirect Anchorable Hide and Close to DockingManager. Updated unit tests. --- .../AvalonDockTest/AnchorablePaneTest.cs | 67 ++++++------------- .../Controls/LayoutAnchorableItem.cs | 2 +- .../Components/AvalonDock/DockingManager.cs | 5 +- .../AvalonDock/Layout/LayoutAnchorable.cs | 26 +++++-- .../Layout/Serialization/LayoutSerializer.cs | 4 +- 5 files changed, 46 insertions(+), 58 deletions(-) diff --git a/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs b/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs index e1eb1540..0ca635b2 100644 --- a/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs +++ b/source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs @@ -63,24 +63,15 @@ public void AnchorablePaneHideCloseEventsFiredTest() dockingManager.AnchorableHiding += (s, e) => isHidingRaised.Add(e.Anchorable); dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); - // Get the visual items - - LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; - LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; - - Assert.IsNotNull(item2); - Assert.IsNotNull(item3); - // Ensure the items can be hidden and closed - - item2.CanClose = true; - item3.CanClose = true; - item2.CanHide = true; - item3.CanHide = true; + windows.Screen2.CanHide = true; + windows.Screen3.CanHide = true; + windows.Screen2.CanClose = true; + windows.Screen3.CanClose = true; // Hide item3 - item3.HideCommand.Execute(null); + windows.Screen3.Hide(); // Ensure only item3 is hidden, and check the correct events were fired @@ -99,7 +90,7 @@ public void AnchorablePaneHideCloseEventsFiredTest() // Close item2 - item2.CloseCommand.Execute(null); + windows.Screen2.Close(); // Check the correct events were fired @@ -148,24 +139,15 @@ public void AnchorablePaneHideCloseEventsCancelledTest() }; dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); - // Get the visual items - - LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; - LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; - - Assert.IsNotNull(item2); - Assert.IsNotNull(item3); - // Ensure the items can be hidden and closed + windows.Screen2.CanHide = true; + windows.Screen3.CanHide = true; + windows.Screen2.CanClose = true; + windows.Screen3.CanClose = true; - item2.CanClose = true; - item3.CanClose = true; - item2.CanHide = true; - item3.CanHide = true; - - // Hide item3 + // Hide Screen3 - item3.HideCommand.Execute(null); + windows.Screen3.Hide(); // Ensure nothing was hidden but cancelled instead, and check the correct events were fired @@ -180,9 +162,9 @@ public void AnchorablePaneHideCloseEventsCancelledTest() isHidingRaised.Clear(); - // Close item2 + // Close Screen2 - item2.CloseCommand.Execute(null); + windows.Screen2.Close(); // Ensure nothing was closed, and check the correct events were fired @@ -226,24 +208,13 @@ public void AnchorablePaneHideEventRedirectTest() }; dockingManager.AnchorableHidden += (s, e) => isHiddenRaised.Add(e.Anchorable); - // Get the visual items - - LayoutAnchorableItem item2 = dockingManager.GetLayoutItemFromModel(windows.Screen2) as LayoutAnchorableItem; - LayoutAnchorableItem item3 = dockingManager.GetLayoutItemFromModel(windows.Screen3) as LayoutAnchorableItem; - - Assert.IsNotNull(item2); - Assert.IsNotNull(item3); + // Ensure the Screen3 can be hidden and closed + windows.Screen3.CanHide = true; + windows.Screen3.CanClose = true; - // Ensure the items can be hidden and closed - - item2.CanClose = true; - item3.CanClose = true; - item2.CanHide = true; - item3.CanHide = true; + // Hide Screen3 - // Hide item3 - - item3.HideCommand.Execute(null); + windows.Screen3.Hide(); // Ensure nothing was hidden but cancelled instead, and check the correct events were fired diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableItem.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableItem.cs index daee7dfa..67e5f0dd 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableItem.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableItem.cs @@ -276,7 +276,7 @@ protected override void OnVisibilityChanged() { switch (Visibility) { - case Visibility.Hidden: case Visibility.Collapsed: _anchorable.Hide(false); break; + case Visibility.Hidden: case Visibility.Collapsed: _anchorable.HideAnchorable(false); break; case Visibility.Visible: _anchorable.Show(); break; } } diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index 6a73991f..633b0f6d 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1962,9 +1962,8 @@ internal void ExecuteHideCommand(LayoutAnchorable anchorable) } if (hidingArgs?.Cancel == true) return; - model.Hide(); - - AnchorableHidden?.Invoke(this, new AnchorableHiddenEventArgs(model)); + if(model.HideAnchorable(true)) + AnchorableHidden?.Invoke(this, new AnchorableHiddenEventArgs(model)); } internal void ExecuteAutoHideCommand(LayoutAnchorable _anchorable) => _anchorable.ToggleAutoHide(); diff --git a/source/Components/AvalonDock/Layout/LayoutAnchorable.cs b/source/Components/AvalonDock/Layout/LayoutAnchorable.cs index 4adda820..68efffde 100644 --- a/source/Components/AvalonDock/Layout/LayoutAnchorable.cs +++ b/source/Components/AvalonDock/Layout/LayoutAnchorable.cs @@ -280,7 +280,16 @@ public override void WriteXml(System.Xml.XmlWriter writer) } /// - public override void Close() => CloseAnchorable(); + public override void Close() + { + if (Root?.Manager != null) + { + var dockingManager = Root.Manager; + dockingManager.ExecuteCloseCommand(this); + } + else + CloseAnchorable(); + } #if TRACE /// @@ -298,24 +307,31 @@ public override void ConsoleDump(int tab) #endregion Overrides #region Public Methods + public void Hide() + { + if (Root?.Manager is DockingManager dockingManager) + dockingManager.ExecuteHideCommand(this); + else + HideAnchorable(true); + } /// Hide this contents. /// Add this content to collection of parent root. /// - public void Hide(bool cancelable = true) + internal bool HideAnchorable(bool cancelable) { if (!IsVisible) { IsSelected = true; IsActive = true; - return; + return false; } if (cancelable) { var args = new CancelEventArgs(); OnHiding(args); - if (args.Cancel) return; + if (args.Cancel) return false; } RaisePropertyChanging(nameof(IsHidden)); @@ -330,6 +346,8 @@ public void Hide(bool cancelable = true) RaisePropertyChanged(nameof(IsVisible)); RaisePropertyChanged(nameof(IsHidden)); NotifyIsVisibleChanged(); + + return true; } /// Show the content. diff --git a/source/Components/AvalonDock/Layout/Serialization/LayoutSerializer.cs b/source/Components/AvalonDock/Layout/Serialization/LayoutSerializer.cs index 7244045f..b455b913 100644 --- a/source/Components/AvalonDock/Layout/Serialization/LayoutSerializer.cs +++ b/source/Components/AvalonDock/Layout/Serialization/LayoutSerializer.cs @@ -89,10 +89,10 @@ protected virtual void FixupLayout(LayoutRoot layout) else if (args.Content != null) lcToFix.Content = args.Content; else if (args.Model.Content != null) - lcToFix.Hide(false); // hide layoutanchorable if client app supplied no content + lcToFix.HideAnchorable(false); // hide layoutanchorable if client app supplied no content } else if (previousAchorable == null) // No Callback and no provious document -> skip this - lcToFix.Hide(false); + lcToFix.HideAnchorable(false); else { // No Callback but previous anchoreable available -> load content from previous document lcToFix.Content = previousAchorable.Content;