mirror of https://github.com/AMT-Cheif/Stylet.git
Conductor optionally disposes children, and WindowConductor never does
This commit is contained in:
parent
dca24b4d5e
commit
20c708ddbe
|
@ -55,17 +55,17 @@ namespace Stylet
|
|||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
this.CloseAndCleanUp(e.OldItems);
|
||||
this.CloseAndCleanUp(e.OldItems, this.DisposeChildren);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
this.ActivateAndSetParent(e.NewItems);
|
||||
this.CloseAndCleanUp(e.OldItems);
|
||||
this.CloseAndCleanUp(e.OldItems, this.DisposeChildren);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
this.ActivateAndSetParent(this.items.Except(this.itemsBeforeReset));
|
||||
this.CloseAndCleanUp(this.itemsBeforeReset.Except(this.items));
|
||||
this.CloseAndCleanUp(this.itemsBeforeReset.Except(this.items), this.DisposeChildren);
|
||||
this.itemsBeforeReset = null;
|
||||
break;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ namespace Stylet
|
|||
{
|
||||
// We've already been deactivated by this point
|
||||
foreach (var item in this.items)
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
|
||||
this.items.Clear();
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ namespace Stylet
|
|||
|
||||
if (await this.CanCloseItem(item))
|
||||
{
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
this.items.Remove(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@ namespace Stylet
|
|||
/// <typeparam name="T">Type of item to be conducted</typeparam>
|
||||
public abstract class ConductorBase<T> : Screen, IConductor<T>, IParent<T>, IChildDelegate where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to dispose a child when it's closed. True by default
|
||||
/// </summary>
|
||||
public virtual bool DisposeChildren { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the Item or Items associated with this Conductor
|
||||
/// </summary>
|
||||
|
@ -85,5 +90,13 @@ namespace Stylet
|
|||
if (typedItem != null)
|
||||
this.CloseItem(typedItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialises a new instance of the <see cref="ConductorBase{T}"/> class
|
||||
/// </summary>
|
||||
public ConductorBase()
|
||||
{
|
||||
this.DisposeChildren = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace Stylet
|
|||
{
|
||||
ScreenExtensions.TryDeactivate(this.ActiveItem);
|
||||
if (closePrevious)
|
||||
this.CloseAndCleanUp(this.ActiveItem);
|
||||
this.CloseAndCleanUp(this.ActiveItem, this.DisposeChildren);
|
||||
|
||||
if (newItem != null)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ namespace Stylet
|
|||
/// </summary>
|
||||
protected override void OnClose()
|
||||
{
|
||||
this.CloseAndCleanUp(this.ActiveItem);
|
||||
this.CloseAndCleanUp(this.ActiveItem, this.DisposeChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Stylet
|
|||
public void Clear()
|
||||
{
|
||||
foreach (var item in this.history)
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
this.history.Clear();
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ namespace Stylet
|
|||
}
|
||||
else if (this.history.Contains(item))
|
||||
{
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
this.history.Remove(item);
|
||||
}
|
||||
}
|
||||
|
@ -103,10 +103,10 @@ namespace Stylet
|
|||
{
|
||||
// We've already been deactivated by this point
|
||||
foreach (var item in this.history)
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
this.history.Clear();
|
||||
|
||||
this.CloseAndCleanUp(this.ActiveItem);
|
||||
this.CloseAndCleanUp(this.ActiveItem, this.DisposeChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ namespace Stylet
|
|||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
this.CloseAndCleanUp(e.OldItems);
|
||||
this.CloseAndCleanUp(e.OldItems, this.DisposeChildren);
|
||||
this.ActiveItemMayHaveBeenRemovedFromItems();
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
this.SetParent(e.NewItems);
|
||||
this.CloseAndCleanUp(e.OldItems);
|
||||
this.CloseAndCleanUp(e.OldItems, this.DisposeChildren);
|
||||
this.ActiveItemMayHaveBeenRemovedFromItems();
|
||||
break;
|
||||
|
||||
|
@ -130,7 +130,7 @@ namespace Stylet
|
|||
}
|
||||
else
|
||||
{
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
}
|
||||
|
||||
this.items.Remove(item);
|
||||
|
@ -181,7 +181,7 @@ namespace Stylet
|
|||
{
|
||||
// We've already been deactivated by this point
|
||||
foreach (var item in this.items)
|
||||
this.CloseAndCleanUp(item);
|
||||
this.CloseAndCleanUp(item, this.DisposeChildren);
|
||||
this.items.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,12 +34,19 @@ namespace Stylet
|
|||
/// Try to close the screen, if it implements IClose
|
||||
/// </summary>
|
||||
/// <param name="screen">Screen to close</param>
|
||||
public static void TryCloseAndDispose(object screen)
|
||||
public static void TryClose(object screen)
|
||||
{
|
||||
var screenAsClose = screen as IClose;
|
||||
if (screenAsClose != null)
|
||||
screenAsClose.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to dispose a screen, if it implements IDisposable
|
||||
/// </summary>
|
||||
/// <param name="screen">Screen to dispose</param>
|
||||
public static void TryDispose(object screen)
|
||||
{
|
||||
var screenAsDispose = screen as IDisposable;
|
||||
if (screenAsDispose != null)
|
||||
screenAsDispose.Dispose();
|
||||
|
@ -76,7 +83,7 @@ namespace Stylet
|
|||
public static void CloseWith(this IClose child, IClose parent)
|
||||
{
|
||||
// Using TryCloseAndDispose ensures that Dispose is called if necessary
|
||||
WeakEventManager<IClose, CloseEventArgs>.AddHandler(parent, "Closed", (o, e) => TryCloseAndDispose(child));
|
||||
WeakEventManager<IClose, CloseEventArgs>.AddHandler(parent, "Closed", (o, e) => TryClose(child));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -31,13 +31,17 @@ namespace Stylet
|
|||
/// <typeparam name="T">Type of conductor</typeparam>
|
||||
/// <param name="parent">Parent</param>
|
||||
/// <param name="item">Item to close and clean up</param>
|
||||
public static void CloseAndCleanUp<T>(this IConductor<T> parent, T item)
|
||||
/// <param name="dispose">True to dispose children as well as close them</param>
|
||||
public static void CloseAndCleanUp<T>(this IConductor<T> parent, T item, bool dispose)
|
||||
{
|
||||
ScreenExtensions.TryCloseAndDispose(item);
|
||||
ScreenExtensions.TryClose(item);
|
||||
|
||||
var itemAsChild = item as IChild;
|
||||
if (itemAsChild != null && itemAsChild.Parent == parent)
|
||||
itemAsChild.Parent = null;
|
||||
|
||||
if (dispose)
|
||||
ScreenExtensions.TryDispose(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -46,11 +50,12 @@ namespace Stylet
|
|||
/// <typeparam name="T">Type of conductor</typeparam>
|
||||
/// <param name="parent">Parent</param>
|
||||
/// <param name="items">List of items to close and clean up</param>
|
||||
public static void CloseAndCleanUp<T>(this IConductor<T> parent, IEnumerable items)
|
||||
/// <param name="dispose">True to dispose children as well as close them</param>
|
||||
public static void CloseAndCleanUp<T>(this IConductor<T> parent, IEnumerable items, bool dispose)
|
||||
{
|
||||
foreach (var item in items.OfType<T>())
|
||||
{
|
||||
parent.CloseAndCleanUp(item);
|
||||
parent.CloseAndCleanUp(item, dispose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace Stylet
|
|||
this.window.Closed -= this.WindowClosed;
|
||||
this.window.Closing -= this.WindowClosing; // Not sure this is required
|
||||
|
||||
ScreenExtensions.TryCloseAndDispose(this.viewModel);
|
||||
ScreenExtensions.TryClose(this.viewModel);
|
||||
}
|
||||
|
||||
private async void WindowClosing(object sender, CancelEventArgs e)
|
||||
|
@ -296,7 +296,7 @@ namespace Stylet
|
|||
if (dialogResult != null)
|
||||
this.window.DialogResult = dialogResult;
|
||||
|
||||
ScreenExtensions.TryCloseAndDispose(this.viewModel);
|
||||
ScreenExtensions.TryClose(this.viewModel);
|
||||
|
||||
this.window.Close();
|
||||
}
|
||||
|
|
|
@ -56,26 +56,26 @@ namespace StyletUnitTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TryCloseAndDisposeClosesIClose()
|
||||
public void TryCloseClosesIClose()
|
||||
{
|
||||
var screen = new Mock<IClose>();
|
||||
ScreenExtensions.TryCloseAndDispose(screen.Object);
|
||||
ScreenExtensions.TryClose(screen.Object);
|
||||
screen.Verify(x => x.Close());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryCloseAndDisposeDisposesIDisposable()
|
||||
public void TryDisposeDisposesIDisposable()
|
||||
{
|
||||
var screen = new Mock<IDisposable>();
|
||||
ScreenExtensions.TryCloseAndDispose(screen.Object);
|
||||
ScreenExtensions.TryDispose(screen.Object);
|
||||
screen.Verify(x => x.Dispose());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryCloseAndDisposeDoesNothingToNonIClose()
|
||||
public void TryCloseDoesNothingToNonIClose()
|
||||
{
|
||||
var screen = new Mock<IActivate>(MockBehavior.Strict);
|
||||
ScreenExtensions.TryCloseAndDispose(screen.Object);
|
||||
ScreenExtensions.TryClose(screen.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
Loading…
Reference in New Issue