ConductorBaseWithActiveItem sets new item as ActiveItem before activating it

Up to now, ScreenExtemsions.TryActivate(newItem) was called
before Conductor.ActiveItem was set to the new item. This commit moves
setting ActiveItem to before TryActivate(newItem) call. This allows for
nested activation - that is, a scenario where newItem can "intercept"
its activation and force parent Conductor to immediately activate
another item inside its OnActivate() override, effectively skipping
newItem without displaying it.

Fixes #140
This commit is contained in:
T.M 2020-07-17 13:42:58 +02:00 committed by Antony Male
parent d4b4fc2ee5
commit 6bc5f646f1
4 changed files with 19 additions and 3 deletions

View File

@ -13,7 +13,7 @@ namespace Stylet.Samples.HelloDialog
public void Close()
{
this.RequestClose(true);
this.RequestClose(null);
}
}
}

View File

@ -27,7 +27,8 @@ namespace Stylet.Samples.HelloDialog
public void ShowDialog()
{
var dialogVm = this.dialogFactory.CreateDialog1();
if (this.windowManager.ShowDialog(dialogVm).GetValueOrDefault())
var result = this.windowManager.ShowDialog(dialogVm);
if (result.GetValueOrDefault())
this.NameString = String.Format("Your name is {0}", dialogVm.Name);
else
this.NameString = "Dialog cancelled";

View File

@ -39,6 +39,8 @@ namespace Stylet
if (closePrevious)
this.CloseAndCleanUp(this.ActiveItem, this.DisposeChildren);
this._activeItem = newItem;
if (newItem != null)
{
this.EnsureItem(newItem);
@ -49,7 +51,6 @@ namespace Stylet
ScreenExtensions.TryDeactivate(newItem);
}
this._activeItem = newItem;
this.NotifyOfPropertyChange("ActiveItem");
}

View File

@ -1,4 +1,5 @@
using Moq;
using Moq.Protected;
using NUnit.Framework;
using Stylet;
using System;
@ -285,5 +286,18 @@ namespace StyletUnitTests
screen.Verify(x => x.Close());
Assert.Null(this.conductor.ActiveItem);
}
[Test]
public void NestedActivateItemsResultsInLastActivatedItemActive()
{
var screen1 = new Mock<Screen>() { CallBase = true };
var screen2 = new Screen();
screen1.Protected().Setup("OnActivate").Callback(() => conductor.ActivateItem(screen2));
((IScreenState)this.conductor).Activate();
this.conductor.ActivateItem(screen1.Object);
Assert.AreEqual(screen2, this.conductor.ActiveItem);
}
}
}