Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add anchorable hide and close notifications to DockingManager #411

Merged
merged 3 commits into from
Dec 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 200 additions & 1 deletion source/AutomationTest/AvalonDockTest/AnchorablePaneTest.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
namespace AvalonDockTest
namespace AvalonDockTest
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.STAExtensions;
using System.Threading.Tasks;
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
Expand All @@ -30,5 +34,200 @@ 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<AnchorablePaneTestWindow> taskResult = WindowHelpers.CreateInvisibleWindowAsync<AnchorablePaneTestWindow>();

taskResult.Wait();

AnchorablePaneTestWindow windows = taskResult.Result;
DockingManager dockingManager = windows.dockingManager;

// These lists hold a record of the anchorable hide and close events

List<LayoutAnchorable> isHidingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isHiddenRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosedRaised = new List<LayoutAnchorable>();

// 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);

// Ensure the items can be hidden and closed
windows.Screen2.CanHide = true;
windows.Screen3.CanHide = true;
windows.Screen2.CanClose = true;
windows.Screen3.CanClose = true;

// Hide item3

windows.Screen3.Hide();

// 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

windows.Screen2.Close();

// 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<AnchorablePaneTestWindow> taskResult = WindowHelpers.CreateInvisibleWindowAsync<AnchorablePaneTestWindow>();

taskResult.Wait();

AnchorablePaneTestWindow windows = taskResult.Result;
DockingManager dockingManager = windows.dockingManager;

// These lists hold a record of the anchorable hide and close events

List<LayoutAnchorable> isHidingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isHiddenRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosedRaised = new List<LayoutAnchorable>();

// 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);

// Ensure the items can be hidden and closed
windows.Screen2.CanHide = true;
windows.Screen3.CanHide = true;
windows.Screen2.CanClose = true;
windows.Screen3.CanClose = true;

// Hide Screen3

windows.Screen3.Hide();

// 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 Screen2

windows.Screen2.Close();

// 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<AnchorablePaneTestWindow> taskResult = WindowHelpers.CreateInvisibleWindowAsync<AnchorablePaneTestWindow>();

taskResult.Wait();

AnchorablePaneTestWindow windows = taskResult.Result;
DockingManager dockingManager = windows.dockingManager;

// These lists hold a record of the anchorable hide and close events

List<LayoutAnchorable> isHidingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isHiddenRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosingRaised = new List<LayoutAnchorable>();
List<LayoutAnchorable> isClosedRaised = new List<LayoutAnchorable>();

// 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);

// Ensure the Screen3 can be hidden and closed
windows.Screen3.CanHide = true;
windows.Screen3.CanClose = true;

// Hide Screen3

windows.Screen3.Hide();

// 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());
}
}
}
35 changes: 35 additions & 0 deletions source/Components/AvalonDock/AnchorableClosedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// 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.
/// </summary>
public class AnchorableClosedEventArgs : EventArgs
{
/// <summary>
/// Class constructor from the anchorables layout model.
/// </summary>
/// <param name="document"></param>
public AnchorableClosedEventArgs(LayoutAnchorable anchorable)
{
Anchorable = anchorable;
}

/// <summary>
/// Gets the model of the anchorable that has been closed.
/// </summary>
public LayoutAnchorable Anchorable { get; private set; }
}
}
35 changes: 35 additions & 0 deletions source/Components/AvalonDock/AnchorableClosingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// 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.
/// </summary>
public class AnchorableClosingEventArgs : CancelEventArgs
{
/// <summary>
/// Class constructor from the anchorable layout model.
/// </summary>
/// <param name="document"></param>
public AnchorableClosingEventArgs(LayoutAnchorable anchorable)
{
Anchorable = anchorable;
}

/// <summary>
/// Gets the model of the anchorable that is about to be closed.
/// </summary>
public LayoutAnchorable Anchorable { get; private set; }
}
}
35 changes: 35 additions & 0 deletions source/Components/AvalonDock/AnchorableHiddenEventArgs.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Implements an event that can be raised to inform the client application about an
/// anchorable that been hidden.
/// </summary>
public class AnchorableHiddenEventArgs : EventArgs
{
/// <summary>
/// Class constructor from the anchorables layout model.
/// </summary>
/// <param name="document"></param>
public AnchorableHiddenEventArgs(LayoutAnchorable anchorable)
{
Anchorable = anchorable;
}

/// <summary>
/// Gets the model of the anchorable that has been hidden.
/// </summary>
public LayoutAnchorable Anchorable { get; private set; }
}
}
40 changes: 40 additions & 0 deletions source/Components/AvalonDock/AnchorableHidingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Implements a Cancelable event that can be raised to ask the client application whether hiding this anchorable
/// is OK or not.
/// </summary>
public class AnchorableHidingEventArgs : CancelEventArgs
{
/// <summary>
/// Class constructor from the anchorable layout model.
/// </summary>
/// <param name="document"></param>
public AnchorableHidingEventArgs(LayoutAnchorable anchorable)
{
Anchorable = anchorable;
}

/// <summary>
/// Gets the model of the anchorable that is about to be hidden.
/// </summary>
public LayoutAnchorable Anchorable { get; private set; }

/// <summary>
/// Gets or sets a value indicating whether an anchorable should be closed instead of hidden
/// </summary>
public bool CloseInsteadOfHide { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
Loading