public async Task ScreenDoesNotNeedToBeActiveItemToCloseIt()
        {
            // conductor conducts conducted
            // conducted.TryCloseAsync() will ask conductor to close it

            var conductor = new Conductor <IScreen> .Collection.OneActive();

            var conducted1 = new StateScreen {
                IsClosable = true
            };
            var conducted2 = new StateScreen {
                IsClosable = true
            };

            // All items are closable
            conductor.Items.Add(conducted1);
            conductor.Items.Add(conducted2);
            // ActivateWith allows synced parent-child activation.
            conducted2.ActivateWith(conductor);
            // ActiveItem is automatically conducted.
            conductor.ActiveItem = conducted1;

            await((IActivate)conductor).ActivateAsync(CancellationToken.None);
            await conducted2.TryCloseAsync();

            Assert.False(conducted2.IsActive);
            Assert.True(conducted2.IsClosed);
        }
        public async Task ConductorTryCloseAsyncWillAskItsConductorToCloseItAndItsChildren()
        {
            // conductor1 conducts conductor2
            // conductor2.TryCloseAsync() will ask conductor1 to close it

            var conductor1 = new Conductor <IScreen>();
            var conductor2 = new Conductor <IScreen> .Collection.OneActive();

            var conducted1 = new StateScreen {
                IsClosable = true
            };
            var conducted2 = new StateScreen {
                IsClosable = true
            };

            conductor1.ActiveItem = conductor2;
            // All items are closable
            conductor2.Items.Add(conducted1);
            conductor2.Items.Add(conducted2);
            // ActivateWith allows synced parent-child activation.
            conducted2.ActivateWith(conductor2);
            // ActiveItem is automatically conducted.
            conductor2.ActiveItem = conducted1;

            await((IActivate)conductor1).ActivateAsync(CancellationToken.None);
            await conductor2.TryCloseAsync();

            Assert.True(conductor1.IsActive);
            Assert.False(conductor2.IsActive);

            Assert.False(conducted1.IsActive);
            Assert.True(conducted1.IsClosed);
            Assert.False(conducted2.IsActive);
            Assert.True(conducted2.IsClosed);
        }
        public async Task AllOrNoneClosingStrategyDoesNotCloseClosableItemsWhenCanCloseIsFalse()
        {
            // AllOrNoneCloseStrategy expected behavior:
            // - Close all items if all can be closed and none otherwise.
            // - ActiveItem is not changed when canClose is false.

            var conductor = new Conductor <IScreen> .Collection.OneActive
            {
                CloseStrategy = new AllOrNoneCloseStrategy <IScreen>()
            };

            var notClosable = new StateScreen
            {
                IsClosable = false
            };
            var closable = new StateScreen
            {
                IsClosable = true
            };

            // Last item is closable, the one before that is not, so no items will be closed.
            conductor.Items.Add(notClosable);
            conductor.Items.Add(closable);
            // ActivateWith allows synced parent-child activation.
            notClosable.ActivateWith(conductor);
            // ActiveItem is automatically conducted.
            conductor.ActiveItem = closable;

            await((IActivate)conductor).ActivateAsync(CancellationToken.None);
            var canClose = await conductor.CanCloseAsync(CancellationToken.None);

            Assert.False(canClose);
            Assert.False(closable.IsClosed);
            Assert.True(closable.IsActive);
            Assert.False(notClosable.IsClosed);
            Assert.True(notClosable.IsActive);

            // The last item remains activated.
            Assert.Equal(closable, conductor.ActiveItem);
        }