mirror of https://github.com/AMT-Cheif/Stylet.git
Merge branch 'release/1.1.0'
This commit is contained in:
commit
193591c0b1
|
@ -54,7 +54,7 @@ namespace Bootstrappers
|
||||||
return this.container.Resolve(type);
|
return this.container.Resolve(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
this.container.Dispose();
|
this.container.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace Bootstrappers
|
||||||
return this.container.Resolve(type);
|
return this.container.Resolve(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
this.container.Dispose();
|
this.container.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Bootstrappers
|
||||||
return this.kernel.Get(type);
|
return this.kernel.Get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
this.kernel.Dispose();
|
this.kernel.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Bootstrappers
|
||||||
return this.container.GetInstance(type);
|
return this.container.GetInstance(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
this.container.Dispose();
|
this.container.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace Bootstrappers
|
||||||
return this.container.Resolve(type);
|
return this.container.Resolve(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
this.container.Dispose();
|
this.container.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
Stylet Changelog
|
Stylet Changelog
|
||||||
================
|
================
|
||||||
|
|
||||||
|
v1.1.0
|
||||||
|
------
|
||||||
|
|
||||||
|
- Backwards-incompatible changes to Bootstrapper: Configure is now called *after* ConfigureIoC, OnStart came before ConfigureIoC, and OnLaunch now happens after Launch
|
||||||
|
- Screen now uses a property enum-based state machine to manage state. IActivate, IDeactivate and IClose have all been rolled into IScreenState
|
||||||
|
- Fix incorrect use of WeakEventManager in ScreenExtensions: ConductWith won't have been working properly
|
||||||
|
- Set WindowStartupLocation to CenterOwner if the user hasn't set it themselves
|
||||||
|
- WindowManager does not set the Title binding (to DisplayName) if it's been set by the user
|
||||||
|
- Actions throw on execute if ActionTarget hasn't changed from the default. This catches an edge-case where Actions are used inside something like a ContextMenu which breaks the visual tree
|
||||||
|
-
|
||||||
|
|
||||||
v1.0.7
|
v1.0.7
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Stylet</id>
|
<id>Stylet</id>
|
||||||
<version>1.0.7</version>
|
<version>1.1.0</version>
|
||||||
<title>Stylet</title>
|
<title>Stylet</title>
|
||||||
<authors>Antony Male</authors>
|
<authors>Antony Male</authors>
|
||||||
<owners>Antony Male</owners>
|
<owners>Antony Male</owners>
|
||||||
|
|
|
@ -31,19 +31,18 @@ namespace Stylet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override sealed void ConfigureBootstrapper()
|
protected override sealed void ConfigureBootstrapper()
|
||||||
{
|
{
|
||||||
// This needs to be called before the container is set up, as it might affect the assemblies
|
|
||||||
this.Configure();
|
|
||||||
|
|
||||||
var builder = new StyletIoCBuilder();
|
var builder = new StyletIoCBuilder();
|
||||||
|
|
||||||
this.DefaultConfigureIoC(builder);
|
this.DefaultConfigureIoC(builder);
|
||||||
this.ConfigureIoC(builder);
|
this.ConfigureIoC(builder);
|
||||||
|
|
||||||
this.Container = builder.BuildContainer();
|
this.Container = builder.BuildContainer();
|
||||||
|
|
||||||
|
this.Configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Override to configure your IoC container, and anything else
|
/// Hook called after the IoC container has been set up
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void Configure() { }
|
protected virtual void Configure() { }
|
||||||
|
|
||||||
|
@ -80,13 +79,12 @@ namespace Stylet
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hook used internall by the Bootstrapper to do things like dispose the IoC container
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">The exit event data</param>
|
public override void Dispose()
|
||||||
protected override void OnExitInternal(ExitEventArgs e)
|
|
||||||
{
|
{
|
||||||
base.OnExitInternal(e);
|
|
||||||
this.Container.Dispose();
|
this.Container.Dispose();
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Stylet
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bootstrapper to be extended by applications which don't want to use StyletIoC as the IoC container.
|
/// Bootstrapper to be extended by applications which don't want to use StyletIoC as the IoC container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BootstrapperBase : IBootstrapper, IViewManagerConfig
|
public abstract class BootstrapperBase : IBootstrapper, IViewManagerConfig, IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current application
|
/// Gets the current application
|
||||||
|
@ -23,7 +23,7 @@ namespace Stylet
|
||||||
/// Gets or sets assemblies which are used for IoC container auto-binding and searching for Views.
|
/// Gets or sets assemblies which are used for IoC container auto-binding and searching for Views.
|
||||||
/// Set this in Configure() if you want to override it
|
/// Set this in Configure() if you want to override it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<Assembly> Assemblies { get; protected set; }
|
public IReadOnlyList<Assembly> Assemblies { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the command line arguments that were passed to the application from either the command prompt or the desktop.
|
/// Gets the command line arguments that were passed to the application from either the command prompt or the desktop.
|
||||||
|
@ -61,13 +61,16 @@ namespace Stylet
|
||||||
// Make life nice for the app - they can handle these by overriding Bootstrapper methods, rather than adding event handlers
|
// Make life nice for the app - they can handle these by overriding Bootstrapper methods, rather than adding event handlers
|
||||||
this.Application.Exit += (o, e) =>
|
this.Application.Exit += (o, e) =>
|
||||||
{
|
{
|
||||||
this.OnExitInternal(e);
|
|
||||||
this.OnExit(e);
|
this.OnExit(e);
|
||||||
|
this.Dispose();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch this logger when needed. If we fetch it now, then no-one will have been given the change to enable the LogManager, and we'll get a NullLogger
|
// Fetch this logger when needed. If we fetch it now, then no-one will have been given the change to enable the LogManager, and we'll get a NullLogger
|
||||||
this.Application.DispatcherUnhandledException += (o, e) => LogManager.GetLogger(typeof(BootstrapperBase)).Error(e.Exception, "Unhandled exception");
|
this.Application.DispatcherUnhandledException += (o, e) =>
|
||||||
this.Application.DispatcherUnhandledException += (o, e) => this.OnUnhandledExecption(e);
|
{
|
||||||
|
LogManager.GetLogger(typeof(BootstrapperBase)).Error(e.Exception, "Unhandled exception");
|
||||||
|
this.OnUnhandledException(e);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -78,12 +81,14 @@ namespace Stylet
|
||||||
{
|
{
|
||||||
// Set this before anything else, so everything can use it
|
// Set this before anything else, so everything can use it
|
||||||
this.Args = args;
|
this.Args = args;
|
||||||
|
this.OnStart();
|
||||||
|
|
||||||
this.ConfigureBootstrapper();
|
this.ConfigureBootstrapper();
|
||||||
|
|
||||||
View.ViewManager = (IViewManager)this.GetInstance(typeof(IViewManager));
|
View.ViewManager = (IViewManager)this.GetInstance(typeof(IViewManager));
|
||||||
|
|
||||||
this.Launch();
|
this.Launch();
|
||||||
|
this.OnLaunch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -93,7 +98,6 @@ namespace Stylet
|
||||||
{
|
{
|
||||||
var windowManager = (IWindowManager)this.GetInstance(typeof(IWindowManager));
|
var windowManager = (IWindowManager)this.GetInstance(typeof(IWindowManager));
|
||||||
windowManager.ShowWindow(this.RootViewModel);
|
windowManager.ShowWindow(this.RootViewModel);
|
||||||
this.OnStartup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -109,15 +113,14 @@ namespace Stylet
|
||||||
public abstract object GetInstance(Type type);
|
public abstract object GetInstance(Type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hook called on application startup. This occurs once the root view has been displayed
|
/// Called on application startup. This occur after this.Args has been assigned, but before the IoC container has been configured
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnStartup() { }
|
protected virtual void OnStart() { }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hook used internall by the Bootstrapper to do things like dispose the IoC container
|
/// Called just after the root View has been displayed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">The exit event data</param>
|
protected virtual void OnLaunch() { }
|
||||||
protected virtual void OnExitInternal(ExitEventArgs e) { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hook called on application exit
|
/// Hook called on application exit
|
||||||
|
@ -129,6 +132,11 @@ namespace Stylet
|
||||||
/// Hook called on an unhandled exception
|
/// Hook called on an unhandled exception
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">The event data</param>
|
/// <param name="e">The event data</param>
|
||||||
protected virtual void OnUnhandledExecption(DispatcherUnhandledExceptionEventArgs e) { }
|
protected virtual void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Dispose() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Stylet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void OnActivate()
|
protected override void OnActivate()
|
||||||
{
|
{
|
||||||
foreach (var item in this.items.OfType<IActivate>())
|
foreach (var item in this.items.OfType<IScreenState>())
|
||||||
{
|
{
|
||||||
item.Activate();
|
item.Activate();
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace Stylet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void OnDeactivate()
|
protected override void OnDeactivate()
|
||||||
{
|
{
|
||||||
foreach (var item in this.items.OfType<IDeactivate>())
|
foreach (var item in this.items.OfType<IScreenState>())
|
||||||
{
|
{
|
||||||
item.Deactivate();
|
item.Deactivate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,51 +23,80 @@ namespace Stylet
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Can be activated, and raises an event when it is actually activated
|
/// State in which a screen can be
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IActivate
|
public enum ScreenState
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activate the object. May not actually cause activation (e.g. if it's already active)
|
/// Screen has been created, but has never had any further transitions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Activate();
|
Initial,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Screen is active. It is likely being displayed to the user
|
||||||
|
/// </summary>
|
||||||
|
Active,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Screen is deactivated. It has either been hidden in favour of another Screen, or the entire window has been minimised
|
||||||
|
/// </summary>
|
||||||
|
Deactivated,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Screen has been closed. It has no associated View, but may yet be displayed again
|
||||||
|
/// </summary>
|
||||||
|
Closed,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Has a concept of state, which can be manipulated by its Conductor
|
||||||
|
/// </summary>
|
||||||
|
public interface IScreenState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current state of the Screen
|
||||||
|
/// </summary>
|
||||||
|
ScreenState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current state is ScreenState.Active
|
||||||
|
/// </summary>
|
||||||
|
bool IsActive { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the Screen's state changed, for any reason
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<ScreenStateChangedEventArgs> StateChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when the object is actually activated
|
/// Raised when the object is actually activated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler<ActivationEventArgs> Activated;
|
event EventHandler<ActivationEventArgs> Activated;
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Can be deactivated, and raises an event when it is actually deactivated
|
/// Raised when the object is actually deactivated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDeactivate
|
event EventHandler<DeactivationEventArgs> Deactivated;
|
||||||
{
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the object is actually closed
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<CloseEventArgs> Closed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activate the object. May not actually cause activation (e.g. if it's already active)
|
||||||
|
/// </summary>
|
||||||
|
void Activate();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deactivate the object. May not actually cause deactivation (e.g. if it's already deactive)
|
/// Deactivate the object. May not actually cause deactivation (e.g. if it's already deactive)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Deactivate();
|
void Deactivate();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when the object is actually deactivated
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler<DeactivationEventArgs> Deactivated;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Can be closed, and raises an event when it is actually closed
|
|
||||||
/// </summary>
|
|
||||||
public interface IClose
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Close the object. May not actually cause closure (e.g. if it's already closed)
|
/// Close the object. May not actually cause closure (e.g. if it's already closed)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when the object is actually closed
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler<CloseEventArgs> Closed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -120,28 +149,101 @@ namespace Stylet
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generalised 'screen' composing all the behaviours expected of a screen
|
/// Generalised 'screen' composing all the behaviours expected of a screen
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IScreen : IViewAware, IHaveDisplayName, IActivate, IDeactivate, IChild, IClose, IGuardClose, IRequestClose
|
public interface IScreen : IViewAware, IHaveDisplayName, IScreenState, IChild, IGuardClose, IRequestClose
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// EventArgs associated with the IActivate.Activated event
|
/// EventArgs associated with the IScreenState.StateChanged event
|
||||||
|
/// </summary>
|
||||||
|
public class ScreenStateChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state being transitioned to
|
||||||
|
/// </summary>
|
||||||
|
public ScreenState NewState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state being transitioned away from
|
||||||
|
/// </summary>
|
||||||
|
public ScreenState PreviousState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialises a new instance of the <see cref="ScreenStateChangedEventArgs"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newState">State being transitioned to</param>
|
||||||
|
/// <param name="previousState">State being transitioned away from</param>
|
||||||
|
public ScreenStateChangedEventArgs(ScreenState newState, ScreenState previousState)
|
||||||
|
{
|
||||||
|
this.NewState = newState;
|
||||||
|
this.PreviousState = previousState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EventArgs associated with the IScreenState.Activated event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ActivationEventArgs : EventArgs
|
public class ActivationEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this is the first time this Screen has been activated, ever
|
||||||
|
/// </summary>
|
||||||
|
public bool IsInitialActivate { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state being transitioned away from
|
||||||
|
/// </summary>
|
||||||
|
public ScreenState PreviousState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialises a new instance of the <see cref="ActivationEventArgs"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="previousState">State being transitioned away from</param>
|
||||||
|
/// <param name="isInitialActivate">True if this is the first time this screen has ever been activated</param>
|
||||||
|
public ActivationEventArgs(ScreenState previousState, bool isInitialActivate)
|
||||||
|
{
|
||||||
|
this.IsInitialActivate = isInitialActivate;
|
||||||
|
this.PreviousState = previousState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// EventArgs associated with the IDeactivate.Deactivated event
|
/// EventArgs associated with the IScreenState.Deactivated event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DeactivationEventArgs : EventArgs
|
public class DeactivationEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state being transitioned away from
|
||||||
|
/// </summary>
|
||||||
|
public ScreenState PreviousState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialises a new instance of the <see cref="DeactivationEventArgs"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="previousState">State being transitioned away from</param>
|
||||||
|
public DeactivationEventArgs(ScreenState previousState)
|
||||||
|
{
|
||||||
|
this.PreviousState = previousState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// EventArgs associated with the IClose.Closed event
|
/// EventArgs associated with the IScreenState.Closed event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CloseEventArgs : EventArgs
|
public class CloseEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state being transitioned away from
|
||||||
|
/// </summary>
|
||||||
|
public ScreenState PreviousState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialises a new instance of the <see cref="CloseEventArgs"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="previousState">State being transitioned away from</param>
|
||||||
|
public CloseEventArgs(ScreenState previousState)
|
||||||
|
{
|
||||||
|
this.PreviousState = previousState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Stylet.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Logger used by Stylet for internal logging
|
||||||
|
/// </summary>
|
||||||
|
public interface ILogger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as info
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
void Info(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as a warning
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
void Warn(string format, params object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log an exception as an error
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exception">Exception to log</param>
|
||||||
|
/// <param name="message">Additional message to add to the exception</param>
|
||||||
|
void Error(Exception exception, string message = null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,113 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Stylet.Logging
|
namespace Stylet.Logging
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Logger used by Stylet for internal logging
|
|
||||||
/// </summary>
|
|
||||||
public interface ILogger
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as info
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
void Info(string format, params object[] args);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as a warning
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
void Warn(string format, params object[] args);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log an exception as an error
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="exception">Exception to log</param>
|
|
||||||
/// <param name="message">Additional message to add to the exception</param>
|
|
||||||
void Error(Exception exception, string message = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ILogger implementation which does nothing - used by default
|
|
||||||
/// </summary>
|
|
||||||
public class NullLogger : ILogger
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as info
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
public void Info(string format, params object[] args) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as a warning
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
public void Warn(string format, params object[] args) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log an exception as an error
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="exception">Exception to log</param>
|
|
||||||
/// <param name="message">Additional message to add to the exception</param>
|
|
||||||
public void Error(Exception exception, string message = null) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ILogger implementation which uses Debug.WriteLine
|
|
||||||
/// </summary>
|
|
||||||
public class TraceLogger : ILogger
|
|
||||||
{
|
|
||||||
private readonly string name;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initialises a new instance of the <see cref="TraceLogger"/> class, with the given name
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">Name of the DebugLogger</param>
|
|
||||||
public TraceLogger(string name)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as info
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
public void Info(string format, params object[] args)
|
|
||||||
{
|
|
||||||
Trace.WriteLine(String.Format("INFO [{1}] {0}", String.Format(format, args), this.name), "Stylet");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log the message as a warning
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="format">A formatted message</param>
|
|
||||||
/// <param name="args">format parameters</param>
|
|
||||||
public void Warn(string format, params object[] args)
|
|
||||||
{
|
|
||||||
Trace.WriteLine(String.Format("WARN [{1}] {0}", String.Format(format, args), this.name), "Stylet");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Log an exception as an error
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="exception">Exception to log</param>
|
|
||||||
/// <param name="message">Additional message to add to the exception</param>
|
|
||||||
public void Error(Exception exception, string message = null)
|
|
||||||
{
|
|
||||||
if (message == null)
|
|
||||||
Trace.WriteLine(String.Format("ERROR [{1}] {0}", exception, this.name), "Stylet");
|
|
||||||
else
|
|
||||||
Trace.WriteLine(String.Format("ERROR [{2}] {0} {1}", message, exception, this.name), "Stylet");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Manager for ILoggers. Used to create new ILoggers, and set up how ILoggers are created
|
/// Manager for ILoggers. Used to create new ILoggers, and set up how ILoggers are created
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Stylet.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ILogger implementation which does nothing - used by default
|
||||||
|
/// </summary>
|
||||||
|
public class NullLogger : ILogger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as info
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
public void Info(string format, params object[] args) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as a warning
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
public void Warn(string format, params object[] args) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log an exception as an error
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exception">Exception to log</param>
|
||||||
|
/// <param name="message">Additional message to add to the exception</param>
|
||||||
|
public void Error(Exception exception, string message = null) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Stylet.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ILogger implementation which uses Debug.WriteLine
|
||||||
|
/// </summary>
|
||||||
|
public class TraceLogger : ILogger
|
||||||
|
{
|
||||||
|
private readonly string name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialises a new instance of the <see cref="TraceLogger"/> class, with the given name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of the DebugLogger</param>
|
||||||
|
public TraceLogger(string name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as info
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
public void Info(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Trace.WriteLine(String.Format("INFO [{1}] {0}", String.Format(format, args), this.name), "Stylet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log the message as a warning
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">A formatted message</param>
|
||||||
|
/// <param name="args">format parameters</param>
|
||||||
|
public void Warn(string format, params object[] args)
|
||||||
|
{
|
||||||
|
Trace.WriteLine(String.Format("WARN [{1}] {0}", String.Format(format, args), this.name), "Stylet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Log an exception as an error
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exception">Exception to log</param>
|
||||||
|
/// <param name="message">Additional message to add to the exception</param>
|
||||||
|
public void Error(Exception exception, string message = null)
|
||||||
|
{
|
||||||
|
if (message == null)
|
||||||
|
Trace.WriteLine(String.Format("ERROR [{1}] {0}", exception, this.name), "Stylet");
|
||||||
|
else
|
||||||
|
Trace.WriteLine(String.Format("ERROR [{2}] {0} {1}", message, exception, this.name), "Stylet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,5 +35,5 @@ using System.Windows.Markup;
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.7.0")]
|
[assembly: AssemblyVersion("1.1.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.7.0")]
|
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||||
|
|
197
Stylet/Screen.cs
197
Stylet/Screen.cs
|
@ -46,47 +46,50 @@ namespace Stylet
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IActivate
|
#region IScreenState
|
||||||
|
|
||||||
|
private ScreenState _state = ScreenState.Initial;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current state of the Screen
|
||||||
|
/// </summary>
|
||||||
|
public virtual ScreenState State
|
||||||
|
{
|
||||||
|
get { return this._state; }
|
||||||
|
protected set
|
||||||
|
{
|
||||||
|
this.SetAndNotify(ref this._state, value);
|
||||||
|
this.NotifyOfPropertyChange(() => this.IsActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current state is ScreenState.Active
|
||||||
|
/// </summary>
|
||||||
|
public bool IsActive
|
||||||
|
{
|
||||||
|
get { return this.State == ScreenState.Active; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when the Screen's state changed, for any reason
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ScreenStateChangedEventArgs> StateChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fired whenever the Screen is activated
|
/// Fired whenever the Screen is activated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<ActivationEventArgs> Activated;
|
public event EventHandler<ActivationEventArgs> Activated;
|
||||||
|
|
||||||
private bool hasBeenActivatedEver;
|
/// <summary>
|
||||||
|
/// Fired whenever the Screen is deactivated
|
||||||
private bool _isActive;
|
/// </summary>
|
||||||
|
public event EventHandler<DeactivationEventArgs> Deactivated;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether this Screen is currently active
|
/// Called whenever this Screen is closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsActive
|
public event EventHandler<CloseEventArgs> Closed;
|
||||||
{
|
|
||||||
get { return this._isActive; }
|
|
||||||
set { this.SetAndNotify(ref this._isActive, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
|
||||||
void IActivate.Activate()
|
|
||||||
{
|
|
||||||
if (this.IsActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.IsActive = true;
|
|
||||||
this.isClosed = false;
|
|
||||||
|
|
||||||
this.logger.Info("Activating");
|
|
||||||
|
|
||||||
if (!this.hasBeenActivatedEver)
|
|
||||||
this.OnInitialActivate();
|
|
||||||
this.hasBeenActivatedEver = true;
|
|
||||||
|
|
||||||
this.OnActivate();
|
|
||||||
|
|
||||||
var handler = this.Activated;
|
|
||||||
if (handler != null)
|
|
||||||
handler(this, new ActivationEventArgs());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called the very first time this Screen is activated, and never again
|
/// Called the very first time this Screen is activated, and never again
|
||||||
|
@ -98,75 +101,87 @@ namespace Stylet
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnActivate() { }
|
protected virtual void OnActivate() { }
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDeactivate
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fired whenever the Screen is deactivated
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler<DeactivationEventArgs> Deactivated;
|
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Stylet.Screen.#Stylet.IDeactivate.Deactivate()", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
|
||||||
void IDeactivate.Deactivate()
|
|
||||||
{
|
|
||||||
if (!this.IsActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.IsActive = false;
|
|
||||||
this.isClosed = false;
|
|
||||||
|
|
||||||
this.logger.Info("Deactivating");
|
|
||||||
|
|
||||||
this.OnDeactivate();
|
|
||||||
|
|
||||||
var handler = this.Deactivated;
|
|
||||||
if (handler != null)
|
|
||||||
handler(this, new DeactivationEventArgs());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called every time this screen is deactivated
|
/// Called every time this screen is deactivated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnDeactivate() { }
|
protected virtual void OnDeactivate() { }
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IClose
|
|
||||||
|
|
||||||
private bool isClosed;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called whenever this Screen is closed
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler<CloseEventArgs> Closed;
|
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
|
||||||
void IClose.Close()
|
|
||||||
{
|
|
||||||
if (this.isClosed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// This will early-exit if it's already deactive
|
|
||||||
((IDeactivate)this).Deactivate();
|
|
||||||
|
|
||||||
this.View = null;
|
|
||||||
this.isClosed = true;
|
|
||||||
|
|
||||||
this.logger.Info("Closing");
|
|
||||||
|
|
||||||
this.OnClose();
|
|
||||||
|
|
||||||
var handler = this.Closed;
|
|
||||||
if (handler != null)
|
|
||||||
handler(this, new CloseEventArgs());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when this screen is closed
|
/// Called when this screen is closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnClose() { }
|
protected virtual void OnClose() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the screen's state to the given state, if it differs from the current state
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newState">State to transition to</param>
|
||||||
|
/// <param name="changedHandler">Called if the transition occurs. Arguments are (newState, previousState)</param>
|
||||||
|
protected virtual void SetState(ScreenState newState, Action<ScreenState, ScreenState> changedHandler)
|
||||||
|
{
|
||||||
|
if (newState == this.State)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var previousState = this.State;
|
||||||
|
this.State = newState;
|
||||||
|
|
||||||
|
this.logger.Info("Setting state from {0} to {1}", previousState, newState);
|
||||||
|
|
||||||
|
changedHandler(previousState, newState);
|
||||||
|
|
||||||
|
var handler = this.StateChanged;
|
||||||
|
if (handler != null)
|
||||||
|
Execute.OnUIThread(() => handler(this, new ScreenStateChangedEventArgs(newState, previousState)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
||||||
|
void IScreenState.Activate()
|
||||||
|
{
|
||||||
|
this.SetState(ScreenState.Active, (oldState, newState) =>
|
||||||
|
{
|
||||||
|
var isInitialActivate = oldState == ScreenState.Initial;
|
||||||
|
if (isInitialActivate)
|
||||||
|
this.OnInitialActivate();
|
||||||
|
|
||||||
|
this.OnActivate();
|
||||||
|
|
||||||
|
var handler = this.Activated;
|
||||||
|
if (handler != null)
|
||||||
|
Execute.OnUIThread(() => handler(this, new ActivationEventArgs(oldState, isInitialActivate)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
||||||
|
void IScreenState.Deactivate()
|
||||||
|
{
|
||||||
|
this.SetState(ScreenState.Deactivated, (oldState, newState) =>
|
||||||
|
{
|
||||||
|
this.OnDeactivate();
|
||||||
|
|
||||||
|
var handler = this.Deactivated;
|
||||||
|
if (handler != null)
|
||||||
|
Execute.OnUIThread(() => handler(this, new DeactivationEventArgs(oldState)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "As this is a framework type, don't want to make it too easy for users to call this method")]
|
||||||
|
void IScreenState.Close()
|
||||||
|
{
|
||||||
|
// Avoid going from Closed back to Deactivated
|
||||||
|
if (this.State != ScreenState.Closed)
|
||||||
|
((IScreenState)this).Deactivate();
|
||||||
|
|
||||||
|
this.View = null;
|
||||||
|
|
||||||
|
this.SetState(ScreenState.Closed, (oldState, newState) =>
|
||||||
|
{
|
||||||
|
this.OnClose();
|
||||||
|
|
||||||
|
var handler = this.Closed;
|
||||||
|
if (handler != null)
|
||||||
|
Execute.OnUIThread(() => handler(this, new CloseEventArgs(oldState)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IViewAware
|
#region IViewAware
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace Stylet
|
||||||
/// <param name="screen">Screen to activate</param>
|
/// <param name="screen">Screen to activate</param>
|
||||||
public static void TryActivate(object screen)
|
public static void TryActivate(object screen)
|
||||||
{
|
{
|
||||||
var screenAsActivate = screen as IActivate;
|
var screenAsScreenState = screen as IScreenState;
|
||||||
if (screenAsActivate != null)
|
if (screenAsScreenState != null)
|
||||||
screenAsActivate.Activate();
|
screenAsScreenState.Activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -25,9 +25,9 @@ namespace Stylet
|
||||||
/// <param name="screen">Screen to deactivate</param>
|
/// <param name="screen">Screen to deactivate</param>
|
||||||
public static void TryDeactivate(object screen)
|
public static void TryDeactivate(object screen)
|
||||||
{
|
{
|
||||||
var screenAsDeactivate = screen as IDeactivate;
|
var screenAsScreenState = screen as IScreenState;
|
||||||
if (screenAsDeactivate != null)
|
if (screenAsScreenState != null)
|
||||||
screenAsDeactivate.Deactivate();
|
screenAsScreenState.Deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -36,9 +36,9 @@ namespace Stylet
|
||||||
/// <param name="screen">Screen to close</param>
|
/// <param name="screen">Screen to close</param>
|
||||||
public static void TryClose(object screen)
|
public static void TryClose(object screen)
|
||||||
{
|
{
|
||||||
var screenAsClose = screen as IClose;
|
var screenAsScreenState = screen as IScreenState;
|
||||||
if (screenAsClose != null)
|
if (screenAsScreenState != null)
|
||||||
screenAsClose.Close();
|
screenAsScreenState.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,9 +58,19 @@ namespace Stylet
|
||||||
/// <example>child.ActivateWith(this)</example>
|
/// <example>child.ActivateWith(this)</example>
|
||||||
/// <param name="child">Child to activate whenever the parent is activated</param>
|
/// <param name="child">Child to activate whenever the parent is activated</param>
|
||||||
/// <param name="parent">Parent to observe</param>
|
/// <param name="parent">Parent to observe</param>
|
||||||
public static void ActivateWith(this IActivate child, IActivate parent)
|
public static void ActivateWith(this IScreenState child, IScreenState parent)
|
||||||
{
|
{
|
||||||
WeakEventManager<IActivate, ActivationEventArgs>.AddHandler(parent, "Activated", (o, e) => child.Activate());
|
var weakChild = new WeakReference<IScreenState>(child);
|
||||||
|
EventHandler<ActivationEventArgs> handler = null;
|
||||||
|
handler = (o, e) =>
|
||||||
|
{
|
||||||
|
IScreenState strongChild;
|
||||||
|
if (weakChild.TryGetTarget(out strongChild))
|
||||||
|
strongChild.Activate();
|
||||||
|
else
|
||||||
|
parent.Activated -= handler;
|
||||||
|
};
|
||||||
|
parent.Activated += handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -69,9 +79,19 @@ namespace Stylet
|
||||||
/// <example>child.DeactivateWith(this)</example>
|
/// <example>child.DeactivateWith(this)</example>
|
||||||
/// <param name="child">Child to deactivate whenever the parent is deacgtivated</param>
|
/// <param name="child">Child to deactivate whenever the parent is deacgtivated</param>
|
||||||
/// <param name="parent">Parent to observe</param>
|
/// <param name="parent">Parent to observe</param>
|
||||||
public static void DeactivateWith(this IDeactivate child, IDeactivate parent)
|
public static void DeactivateWith(this IScreenState child, IScreenState parent)
|
||||||
{
|
{
|
||||||
WeakEventManager<IDeactivate, DeactivationEventArgs>.AddHandler(parent, "Deactivated", (o, e) => child.Deactivate());
|
var weakChild = new WeakReference<IScreenState>(child);
|
||||||
|
EventHandler<DeactivationEventArgs> handler = null;
|
||||||
|
handler = (o, e) =>
|
||||||
|
{
|
||||||
|
IScreenState strongChild;
|
||||||
|
if (weakChild.TryGetTarget(out strongChild))
|
||||||
|
strongChild.Deactivate();
|
||||||
|
else
|
||||||
|
parent.Deactivated -= handler;
|
||||||
|
};
|
||||||
|
parent.Deactivated += handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -80,23 +100,28 @@ namespace Stylet
|
||||||
/// <example>child.CloseWith(this)</example>
|
/// <example>child.CloseWith(this)</example>
|
||||||
/// <param name="child">Child to close when the parent is closed</param>
|
/// <param name="child">Child to close when the parent is closed</param>
|
||||||
/// <param name="parent">Parent to observe</param>
|
/// <param name="parent">Parent to observe</param>
|
||||||
public static void CloseWith(this IClose child, IClose parent)
|
public static void CloseWith(this IScreenState child, IScreenState parent)
|
||||||
{
|
{
|
||||||
// Using TryCloseAndDispose ensures that Dispose is called if necessary
|
var weakChild = new WeakReference<IScreenState>(child);
|
||||||
WeakEventManager<IClose, CloseEventArgs>.AddHandler(parent, "Closed", (o, e) => TryClose(child));
|
EventHandler<CloseEventArgs> handler = null;
|
||||||
|
handler = (o, e) =>
|
||||||
|
{
|
||||||
|
IScreenState strongChild;
|
||||||
|
if (weakChild.TryGetTarget(out strongChild))
|
||||||
|
TryClose(strongChild);
|
||||||
|
else
|
||||||
|
parent.Closed -= handler;
|
||||||
|
};
|
||||||
|
parent.Closed += handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activate, Deactivate, or Close the child whenever the parent is Activated, Deactivated, or Closed
|
/// Activate, Deactivate, or Close the child whenever the parent is Activated, Deactivated, or Closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <example>child.ConductWith(this)</example>
|
/// <example>child.ConductWith(this)</example>
|
||||||
/// <typeparam name="TChild">Type of the child</typeparam>
|
|
||||||
/// <typeparam name="TParent">Type of the parent</typeparam>
|
|
||||||
/// <param name="child">Child to conduct with the parent</param>
|
/// <param name="child">Child to conduct with the parent</param>
|
||||||
/// <param name="parent">Parent to observe</param>
|
/// <param name="parent">Parent to observe</param>
|
||||||
public static void ConductWith<TChild, TParent>(this TChild child, TParent parent)
|
public static void ConductWith(this IScreenState child, IScreenState parent)
|
||||||
where TChild : IActivate, IDeactivate, IClose
|
|
||||||
where TParent : IActivate, IDeactivate, IClose
|
|
||||||
{
|
{
|
||||||
child.ActivateWith(parent);
|
child.ActivateWith(parent);
|
||||||
child.DeactivateWith(parent);
|
child.DeactivateWith(parent);
|
||||||
|
|
|
@ -49,6 +49,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="IDispatcher.cs" />
|
<Compile Include="IDispatcher.cs" />
|
||||||
<Compile Include="INotifyCollectionChanging.cs" />
|
<Compile Include="INotifyCollectionChanging.cs" />
|
||||||
|
<Compile Include="Logging\ILogger.cs" />
|
||||||
|
<Compile Include="Logging\NullLogger.cs" />
|
||||||
|
<Compile Include="Logging\TraceLogger.cs" />
|
||||||
<Compile Include="StyletIoC\Creation\ICreator.cs" />
|
<Compile Include="StyletIoC\Creation\ICreator.cs" />
|
||||||
<Compile Include="StyletIoC\Creation\IRegistration.cs" />
|
<Compile Include="StyletIoC\Creation\IRegistration.cs" />
|
||||||
<Compile Include="StyletIoC\Internal\Builders\BuilderAbstractFactoryBinding.cs" />
|
<Compile Include="StyletIoC\Internal\Builders\BuilderAbstractFactoryBinding.cs" />
|
||||||
|
|
|
@ -173,6 +173,18 @@ namespace StyletIoC
|
||||||
/// <param name="assemblies">Assembly(s) to search, or leave empty / null to search the current assembly</param>
|
/// <param name="assemblies">Assembly(s) to search, or leave empty / null to search the current assembly</param>
|
||||||
void Autobind(params Assembly[] assemblies);
|
void Autobind(params Assembly[] assemblies);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a single module to this builder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module">Module to add</param>
|
||||||
|
void AddModule(StyletIoCModule module);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add many modules to this builder
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modules">Modules to add</param>
|
||||||
|
void AddModules(params StyletIoCModule[] modules);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Once all bindings have been set, build an IContainer from which instances can be fetches
|
/// Once all bindings have been set, build an IContainer from which instances can be fetches
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Stylet
|
||||||
/// Gets the assemblies which are used for IoC container auto-binding and searching for Views.
|
/// Gets the assemblies which are used for IoC container auto-binding and searching for Views.
|
||||||
/// Set this in Configure() if you want to override it
|
/// Set this in Configure() if you want to override it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<Assembly> Assemblies { get; }
|
IReadOnlyList<Assembly> Assemblies { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a type, use the IoC container to fetch an instance of it
|
/// Given a type, use the IoC container to fetch an instance of it
|
||||||
|
@ -73,7 +73,7 @@ namespace Stylet
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the assemblies searched for View types
|
/// Gets or sets the assemblies searched for View types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IList<Assembly> Assemblies { get; set; }
|
protected IReadOnlyList<Assembly> Assemblies { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the factory used to create view instances from their type
|
/// Gets or sets the factory used to create view instances from their type
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace Stylet
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveDisplayName = viewModel as IHaveDisplayName;
|
var haveDisplayName = viewModel as IHaveDisplayName;
|
||||||
if (haveDisplayName != null && BindingOperations.GetBindingBase(window, Window.TitleProperty) == null)
|
if (haveDisplayName != null && String.IsNullOrEmpty(window.Title) && BindingOperations.GetBindingBase(window, Window.TitleProperty) == null)
|
||||||
{
|
{
|
||||||
var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };
|
var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };
|
||||||
window.SetBinding(Window.TitleProperty, binding);
|
window.SetBinding(Window.TitleProperty, binding);
|
||||||
|
@ -153,6 +153,7 @@ namespace Stylet
|
||||||
logger.Error(e, "This can occur when the application is closing down");
|
logger.Error(e, "This can occur when the application is closing down");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Displaying ViewModel {0} with View {1} as a Dialog", viewModel, window);
|
logger.Info("Displaying ViewModel {0} with View {1} as a Dialog", viewModel, window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -160,6 +161,11 @@ namespace Stylet
|
||||||
logger.Info("Displaying ViewModel {0} with View {1} as a Window", viewModel, window);
|
logger.Info("Displaying ViewModel {0} with View {1} as a Window", viewModel, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If and only if they haven't tried to position the window themselves...
|
||||||
|
// Has to be done after we're attempted to set the owner
|
||||||
|
if (window.WindowStartupLocation == WindowStartupLocation.Manual && Double.IsNaN(window.Top) && Double.IsNaN(window.Left))
|
||||||
|
window.WindowStartupLocation = window.Owner == null ? WindowStartupLocation.CenterScreen : WindowStartupLocation.CenterOwner;
|
||||||
|
|
||||||
// This gets itself retained by the window, by registering events
|
// This gets itself retained by the window, by registering events
|
||||||
// ReSharper disable once ObjectCreationAsStatement
|
// ReSharper disable once ObjectCreationAsStatement
|
||||||
new WindowConductor(window, viewModel);
|
new WindowConductor(window, viewModel);
|
||||||
|
@ -193,15 +199,15 @@ namespace Stylet
|
||||||
|
|
||||||
ScreenExtensions.TryActivate(this.viewModel);
|
ScreenExtensions.TryActivate(this.viewModel);
|
||||||
|
|
||||||
var viewModelAsClose = this.viewModel as IClose;
|
var viewModelAsScreenState = this.viewModel as IScreenState;
|
||||||
if (viewModelAsClose != null)
|
if (viewModelAsScreenState != null)
|
||||||
|
{
|
||||||
|
window.StateChanged += this.WindowStateChanged;
|
||||||
window.Closed += this.WindowClosed;
|
window.Closed += this.WindowClosed;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.viewModel is IGuardClose)
|
if (this.viewModel is IGuardClose)
|
||||||
window.Closing += this.WindowClosing;
|
window.Closing += this.WindowClosing;
|
||||||
|
|
||||||
if (this.viewModel is IActivate || this.viewModel is IDeactivate)
|
|
||||||
window.StateChanged += this.WindowStateChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowStateChanged(object sender, EventArgs e)
|
private void WindowStateChanged(object sender, EventArgs e)
|
||||||
|
|
|
@ -125,6 +125,15 @@ namespace Stylet.Xaml
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The View.ActionTarget was not set. This probably means the item is in a ContextMenu/Popup
|
||||||
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable")]
|
||||||
|
public class ActionNotSetException : Exception
|
||||||
|
{
|
||||||
|
internal ActionNotSetException(string message) : base(message) { }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Action Target was null, and shouldn't have been (NullTarget = Throw)
|
/// The Action Target was null, and shouldn't have been (NullTarget = Throw)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -81,7 +81,10 @@ namespace Stylet.Xaml
|
||||||
// If they've opted to throw if the target is null, then this will cause that exception.
|
// If they've opted to throw if the target is null, then this will cause that exception.
|
||||||
// We'll just wait until the ActionTarget is assigned, and we're called again
|
// We'll just wait until the ActionTarget is assigned, and we're called again
|
||||||
if (newTarget == View.InitialActionTarget)
|
if (newTarget == View.InitialActionTarget)
|
||||||
|
{
|
||||||
|
this.target = newTarget;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.guardPropertyGetter = null;
|
this.guardPropertyGetter = null;
|
||||||
if (newTarget == null)
|
if (newTarget == null)
|
||||||
|
@ -95,7 +98,7 @@ namespace Stylet.Xaml
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Info("ActionTarget on element {0} is null (method name is {1}), nut NullTarget is not Throw, so carrying on", this.Subject, this.MethodName);
|
logger.Info("ActionTarget on element {0} is null (method name is {1}), but NullTarget is not Throw, so carrying on", this.Subject, this.MethodName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -147,12 +150,11 @@ namespace Stylet.Xaml
|
||||||
if (oldTarget != null)
|
if (oldTarget != null)
|
||||||
oldTarget.PropertyChanged -= this.PropertyChangedHandler;
|
oldTarget.PropertyChanged -= this.PropertyChangedHandler;
|
||||||
|
|
||||||
this.target = newTarget;
|
|
||||||
|
|
||||||
var inpc = newTarget as INotifyPropertyChanged;
|
var inpc = newTarget as INotifyPropertyChanged;
|
||||||
if (this.guardPropertyGetter != null && inpc != null)
|
if (this.guardPropertyGetter != null && inpc != null)
|
||||||
inpc.PropertyChanged += this.PropertyChangedHandler;
|
inpc.PropertyChanged += this.PropertyChangedHandler;
|
||||||
|
|
||||||
|
this.target = newTarget;
|
||||||
this.targetMethodInfo = targetMethodInfo;
|
this.targetMethodInfo = targetMethodInfo;
|
||||||
|
|
||||||
this.UpdateCanExecute();
|
this.UpdateCanExecute();
|
||||||
|
@ -183,6 +185,13 @@ namespace Stylet.Xaml
|
||||||
/// <returns>true if this command can be executed; otherwise, false.</returns>
|
/// <returns>true if this command can be executed; otherwise, false.</returns>
|
||||||
public bool CanExecute(object parameter)
|
public bool CanExecute(object parameter)
|
||||||
{
|
{
|
||||||
|
// This can happen if the ActionTarget hasn't been set from its default -
|
||||||
|
// e.g. if the button/etc in question is in a ContextMenu/Popup, which attached properties
|
||||||
|
// aren't inherited by.
|
||||||
|
// Show the control as enabled, but throw if they try and click on it
|
||||||
|
if (this.target == View.InitialActionTarget)
|
||||||
|
return true;
|
||||||
|
|
||||||
// It's enabled only if both the targetNull and actionNonExistent tests pass
|
// It's enabled only if both the targetNull and actionNonExistent tests pass
|
||||||
|
|
||||||
// Throw is handled when the target is set
|
// Throw is handled when the target is set
|
||||||
|
@ -215,6 +224,17 @@ namespace Stylet.Xaml
|
||||||
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
|
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
|
||||||
public void Execute(object parameter)
|
public void Execute(object parameter)
|
||||||
{
|
{
|
||||||
|
// If we've made it this far and the target is still the default, then something's wrong
|
||||||
|
// Make sure they know
|
||||||
|
if (this.target == View.InitialActionTarget)
|
||||||
|
{
|
||||||
|
var e = new ActionNotSetException(String.Format("View.ActionTarget not on control {0} (method {1}). " +
|
||||||
|
"This probably means the control hasn't inherited it from a parent, e.g. because a ContextMenu or Popup sits in the visual tree. " +
|
||||||
|
"You will need so set 's:View.ActionTarget' explicitly. See the wiki for more details.", this.Subject, this.MethodName));
|
||||||
|
logger.Error(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
// Any throwing would have been handled prior to this
|
// Any throwing would have been handled prior to this
|
||||||
if (this.target == null || this.targetMethodInfo == null)
|
if (this.target == null || this.targetMethodInfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -77,7 +77,10 @@ namespace Stylet.Xaml
|
||||||
// If they've opted to throw if the target is null, then this will cause that exception.
|
// If they've opted to throw if the target is null, then this will cause that exception.
|
||||||
// We'll just wait until the ActionTarget is assigned, and we're called again
|
// We'll just wait until the ActionTarget is assigned, and we're called again
|
||||||
if (newTarget == View.InitialActionTarget)
|
if (newTarget == View.InitialActionTarget)
|
||||||
|
{
|
||||||
|
this.target = newTarget;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newTarget == null)
|
if (newTarget == null)
|
||||||
{
|
{
|
||||||
|
@ -146,6 +149,17 @@ namespace Stylet.Xaml
|
||||||
// ReSharper disable once UnusedMember.Local
|
// ReSharper disable once UnusedMember.Local
|
||||||
private void InvokeCommand(object sender, EventArgs e)
|
private void InvokeCommand(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
// If we've made it this far and the target is still the default, then something's wrong
|
||||||
|
// Make sure they know
|
||||||
|
if (this.target == View.InitialActionTarget)
|
||||||
|
{
|
||||||
|
var ex = new ActionNotSetException(String.Format("View.ActionTarget not on control {0} (method {1}). " +
|
||||||
|
"This probably means the control hasn't inherited it from a parent, e.g. because a ContextMenu or Popup sits in the visual tree. " +
|
||||||
|
"You will need so set 's:View.ActionTarget' explicitly. See the wiki for more details.", this.subject, this.methodName));
|
||||||
|
logger.Error(ex);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
// Any throwing will have been handled above
|
// Any throwing will have been handled above
|
||||||
if (this.target == null || this.targetMethodInfo == null)
|
if (this.target == null || this.targetMethodInfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -17,9 +17,9 @@ namespace StyletIntegrationTests
|
||||||
LogManager.Enabled = true;
|
LogManager.Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUnhandledExecption(System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
protected override void OnUnhandledException(System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnUnhandledExecption(e); // Calling this just to trigger some code coverage
|
base.OnUnhandledException(e); // Calling this just to trigger some code coverage
|
||||||
var message = e.Exception.Message;
|
var message = e.Exception.Message;
|
||||||
if (e.Exception is TargetInvocationException)
|
if (e.Exception is TargetInvocationException)
|
||||||
message = e.Exception.InnerException.Message;
|
message = e.Exception.InnerException.Message;
|
||||||
|
|
|
@ -51,10 +51,10 @@ namespace StyletUnitTests
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnStartupCalled;
|
public bool OnStartCalled;
|
||||||
protected override void OnStartup()
|
protected override void OnStart()
|
||||||
{
|
{
|
||||||
this.OnStartupCalled = true;
|
this.OnStartCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnExitCalled;
|
public bool OnExitCalled;
|
||||||
|
@ -147,7 +147,7 @@ namespace StyletUnitTests
|
||||||
public void StartCallsOnStartup()
|
public void StartCallsOnStartup()
|
||||||
{
|
{
|
||||||
this.bootstrapper.Start(new string[0]);
|
this.bootstrapper.Start(new string[0]);
|
||||||
Assert.True(this.bootstrapper.OnStartupCalled);
|
Assert.True(this.bootstrapper.OnStartCalled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,6 @@ namespace StyletUnitTests
|
||||||
builder.Bind<I1>().To<C1>();
|
builder.Bind<I1>().To<C1>();
|
||||||
base.ConfigureIoC(builder);
|
base.ConfigureIoC(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new void OnExitInternal(ExitEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnExitInternal(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MyBootstrapper<RootViewModel> bootstrapper;
|
private MyBootstrapper<RootViewModel> bootstrapper;
|
||||||
|
@ -92,11 +87,11 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void OnExitInternalDisposesContainer()
|
public void DisposeDisposesContainer()
|
||||||
{
|
{
|
||||||
var container = new Mock<IContainer>();
|
var container = new Mock<IContainer>();
|
||||||
this.bootstrapper.Container = container.Object;
|
this.bootstrapper.Container = container.Object;
|
||||||
this.bootstrapper.OnExitInternal(null);
|
this.bootstrapper.Dispose();
|
||||||
container.Verify(x => x.Dispose());
|
container.Verify(x => x.Dispose());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,15 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("woo");
|
throw new InvalidOperationException("woo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanDoSomethingWithUnsuccessfulGuardMethod
|
||||||
|
{
|
||||||
|
get { throw new InvalidOperationException("foo"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoSomethingWithUnsuccessfulGuardMethod()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Target2
|
private class Target2
|
||||||
|
@ -221,5 +230,29 @@ namespace StyletUnitTests
|
||||||
var e = Assert.Throws<InvalidOperationException>(() => cmd.Execute(null));
|
var e = Assert.Throws<InvalidOperationException>(() => cmd.Execute(null));
|
||||||
Assert.AreEqual("woo", e.Message);
|
Assert.AreEqual("woo", e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PropagatesGuardPropertException()
|
||||||
|
{
|
||||||
|
var cmd = new CommandAction(this.subject, "DoSomethingWithUnsuccessfulGuardMethod", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||||
|
var e = Assert.Throws<InvalidOperationException>(() => cmd.CanExecute(null));
|
||||||
|
Assert.AreEqual("foo", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ControlIsEnabledIfTargetIsDefault()
|
||||||
|
{
|
||||||
|
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||||
|
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||||
|
Assert.True(cmd.CanExecute(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ExecuteThrowsIfTargetIsDefault()
|
||||||
|
{
|
||||||
|
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||||
|
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||||
|
Assert.Throws<ActionNotSetException>(() => cmd.Execute(null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace StyletUnitTests
|
||||||
public void ActivateItemActivatesfConductorIsActive()
|
public void ActivateItemActivatesfConductorIsActive()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ namespace StyletUnitTests
|
||||||
public void ActivateItemDoesNotDeactivateIfConductorIsActive()
|
public void ActivateItemDoesNotDeactivateIfConductorIsActive()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Deactivate(), Times.Never);
|
screen.Verify(x => x.Deactivate(), Times.Never);
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,9 @@ namespace StyletUnitTests
|
||||||
public void DeactiveDeactivatesItems()
|
public void DeactiveDeactivatesItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IDeactivate)this.conductor).Deactivate();
|
((IScreenState)this.conductor).Deactivate();
|
||||||
screen.Verify(x => x.Deactivate());
|
screen.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ namespace StyletUnitTests
|
||||||
public void ClosingClosesAllItems()
|
public void ClosingClosesAllItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen.Verify(x => x.Close());
|
screen.Verify(x => x.Close());
|
||||||
screen.Verify(x => x.Dispose());
|
screen.Verify(x => x.Dispose());
|
||||||
Assert.AreEqual(0, this.conductor.Items.Count);
|
Assert.AreEqual(0, this.conductor.Items.Count);
|
||||||
|
@ -122,7 +122,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void AddingItemActivatesAndSetsParent()
|
public void AddingItemActivatesAndSetsParent()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
this.conductor.Items.Add(screen.Object);
|
this.conductor.Items.Add(screen.Object);
|
||||||
screen.VerifySet(x => x.Parent = this.conductor);
|
screen.VerifySet(x => x.Parent = this.conductor);
|
||||||
|
@ -211,7 +211,7 @@ namespace StyletUnitTests
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen1.Verify(x => x.Close());
|
screen1.Verify(x => x.Close());
|
||||||
screen1.Verify(x => x.Dispose());
|
screen1.Verify(x => x.Dispose());
|
||||||
screen1.VerifySet(x => x.Parent = null);
|
screen1.VerifySet(x => x.Parent = null);
|
||||||
|
@ -237,7 +237,7 @@ namespace StyletUnitTests
|
||||||
public void AddRangeActivatesAddedItems()
|
public void AddRangeActivatesAddedItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
|
|
||||||
this.conductor.Items.AddRange(new[] { screen.Object });
|
this.conductor.Items.AddRange(new[] { screen.Object });
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void InitialActivateActivatesItemIfConductorIsActive()
|
public void InitialActivateActivatesItemIfConductorIsActive()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
|
@ -70,17 +70,17 @@ namespace StyletUnitTests
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate(), Times.Never);
|
screen.Verify(x => x.Activate(), Times.Never);
|
||||||
|
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DeactivatesActiveItemWhenDeactivated()
|
public void DeactivatesActiveItemWhenDeactivated()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IDeactivate)this.conductor).Deactivate();
|
((IScreenState)this.conductor).Deactivate();
|
||||||
screen.Verify(x => x.Deactivate());
|
screen.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
|
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
@ -100,7 +100,7 @@ namespace StyletUnitTests
|
||||||
public void ActivatingCurrentScreenReactivatesScreen()
|
public void ActivatingCurrentScreenReactivatesScreen()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate(), Times.Exactly(2));
|
screen.Verify(x => x.Activate(), Times.Exactly(2));
|
||||||
|
@ -113,7 +113,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
var screen2 = new Mock<IMyScreen>();
|
var screen2 = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
this.conductor.CloseItem(screen2.Object);
|
this.conductor.CloseItem(screen2.Object);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ namespace StyletUnitTests
|
||||||
public void DeactiveDoesNotChangeActiveItem()
|
public void DeactiveDoesNotChangeActiveItem()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
this.conductor.DeactivateItem(screen.Object);
|
this.conductor.DeactivateItem(screen.Object);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ namespace StyletUnitTests
|
||||||
public void SettingActiveItemActivatesItem()
|
public void SettingActiveItemActivatesItem()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActiveItem =screen.Object;
|
this.conductor.ActiveItem =screen.Object;
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
||||||
|
@ -206,7 +206,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void DeactivatingActiveItemGoesBack()
|
public void DeactivatingActiveItemGoesBack()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void ClearClosesAllItemsExceptCurrent()
|
public void ClearClosesAllItemsExceptCurrent()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
|
@ -248,7 +248,7 @@ namespace StyletUnitTests
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen1.Verify(x => x.Close());
|
screen1.Verify(x => x.Close());
|
||||||
screen1.VerifySet(x => x.Parent = null);
|
screen1.VerifySet(x => x.Parent = null);
|
||||||
screen2.Verify(x => x.Close());
|
screen2.Verify(x => x.Close());
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace StyletUnitTests
|
||||||
public void ActivatingItemActivatesAndAddsToItems()
|
public void ActivatingItemActivatesAndAddsToItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
|
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
|
@ -46,7 +46,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
|
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
@ -62,7 +62,7 @@ namespace StyletUnitTests
|
||||||
public void SettingActiveItemActivatesItem()
|
public void SettingActiveItemActivatesItem()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActiveItem = screen.Object;
|
this.conductor.ActiveItem = screen.Object;
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
||||||
|
@ -74,7 +74,7 @@ namespace StyletUnitTests
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
var screen3 = new Mock<IScreen>();
|
var screen3 = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
|
|
||||||
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object, screen3.Object });
|
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object, screen3.Object });
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
@ -92,7 +92,7 @@ namespace StyletUnitTests
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
var screen3 = new Mock<IScreen>();
|
var screen3 = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
|
|
||||||
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object, screen3.Object });
|
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object, screen3.Object });
|
||||||
this.conductor.ActivateItem(screen3.Object);
|
this.conductor.ActivateItem(screen3.Object);
|
||||||
|
@ -116,7 +116,7 @@ namespace StyletUnitTests
|
||||||
public void ActivateItemDoesActiveIfConductorIsActive()
|
public void ActivateItemDoesActiveIfConductorIsActive()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
@ -125,9 +125,9 @@ namespace StyletUnitTests
|
||||||
public void DeactiveDeactivatesItems()
|
public void DeactiveDeactivatesItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IDeactivate)this.conductor).Deactivate();
|
((IScreenState)this.conductor).Deactivate();
|
||||||
screen.Verify(x => x.Deactivate());
|
screen.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +135,9 @@ namespace StyletUnitTests
|
||||||
public void ClosingClosesAllItems()
|
public void ClosingClosesAllItems()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen.Verify(x => x.Close());
|
screen.Verify(x => x.Close());
|
||||||
screen.Verify(x => x.Dispose());
|
screen.Verify(x => x.Dispose());
|
||||||
Assert.AreEqual(0, this.conductor.Items.Count);
|
Assert.AreEqual(0, this.conductor.Items.Count);
|
||||||
|
@ -182,7 +182,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IScreen>();
|
var screen1 = new Mock<IScreen>();
|
||||||
var screen2 = new Mock<IScreen>();
|
var screen2 = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
|
|
||||||
// This is an implementation detail
|
// This is an implementation detail
|
||||||
|
@ -229,7 +229,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void RemovingActiveItemActivatesAnotherItem()
|
public void RemovingActiveItemActivatesAnotherItem()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
var screen2 = new Mock<IMyScreen>();
|
var screen2 = new Mock<IMyScreen>();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
|
@ -310,7 +310,7 @@ namespace StyletUnitTests
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
screen1.SetupGet(x => x.Parent).Returns(this.conductor);
|
screen1.SetupGet(x => x.Parent).Returns(this.conductor);
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen1.Verify(x => x.Close());
|
screen1.Verify(x => x.Close());
|
||||||
screen1.Verify(x => x.Dispose());
|
screen1.Verify(x => x.Dispose());
|
||||||
screen1.VerifySet(x => x.Parent = null);
|
screen1.VerifySet(x => x.Parent = null);
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void InitialActivateActivatesItemIfConductorIsActive()
|
public void InitialActivateActivatesItemIfConductorIsActive()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
|
@ -62,17 +62,17 @@ namespace StyletUnitTests
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate(), Times.Never);
|
screen.Verify(x => x.Activate(), Times.Never);
|
||||||
|
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DeactivatesActiveItemWhenDeactivated()
|
public void DeactivatesActiveItemWhenDeactivated()
|
||||||
{
|
{
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IDeactivate)this.conductor).Deactivate();
|
((IScreenState)this.conductor).Deactivate();
|
||||||
screen.Verify(x => x.Deactivate());
|
screen.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
var screen2 = new Mock<IMyScreen>();
|
var screen2 = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
|
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
@ -94,7 +94,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
var screen2 = new Mock<IMyScreen>();
|
var screen2 = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(false));
|
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(false));
|
||||||
this.conductor.ActivateItem(screen2.Object);
|
this.conductor.ActivateItem(screen2.Object);
|
||||||
|
@ -108,7 +108,7 @@ namespace StyletUnitTests
|
||||||
public void ActivatingCurrentScreenReactivatesScreen()
|
public void ActivatingCurrentScreenReactivatesScreen()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
screen.Verify(x => x.Activate(), Times.Exactly(2));
|
screen.Verify(x => x.Activate(), Times.Exactly(2));
|
||||||
|
@ -120,7 +120,7 @@ namespace StyletUnitTests
|
||||||
public void SettingActiveItemActivatesItem()
|
public void SettingActiveItemActivatesItem()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActiveItem = screen.Object;
|
this.conductor.ActiveItem = screen.Object;
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
Assert.AreEqual(this.conductor.ActiveItem, screen.Object);
|
||||||
|
@ -131,7 +131,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
var screen2 = new Mock<IMyScreen>();
|
var screen2 = new Mock<IMyScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
this.conductor.CloseItem(screen2.Object);
|
this.conductor.CloseItem(screen2.Object);
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ namespace StyletUnitTests
|
||||||
public void DeactiveDoesNotChangeActiveItem()
|
public void DeactiveDoesNotChangeActiveItem()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IScreen>();
|
var screen = new Mock<IScreen>();
|
||||||
((IActivate)this.conductor).Activate();
|
((IScreenState)this.conductor).Activate();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
this.conductor.DeactivateItem(screen.Object);
|
this.conductor.DeactivateItem(screen.Object);
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ namespace StyletUnitTests
|
||||||
var screen1 = new Mock<IMyScreen>();
|
var screen1 = new Mock<IMyScreen>();
|
||||||
screen1.SetupGet(x => x.Parent).Returns(this.conductor);
|
screen1.SetupGet(x => x.Parent).Returns(this.conductor);
|
||||||
this.conductor.ActivateItem(screen1.Object);
|
this.conductor.ActivateItem(screen1.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen1.Verify(x => x.Close());
|
screen1.Verify(x => x.Close());
|
||||||
screen1.VerifySet(x => x.Parent = null);
|
screen1.VerifySet(x => x.Parent = null);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen.Verify(x => x.Dispose());
|
screen.Verify(x => x.Dispose());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ namespace StyletUnitTests
|
||||||
this.conductor.DisposeChildren = false;
|
this.conductor.DisposeChildren = false;
|
||||||
var screen = new Mock<IMyScreen>();
|
var screen = new Mock<IMyScreen>();
|
||||||
this.conductor.ActivateItem(screen.Object);
|
this.conductor.ActivateItem(screen.Object);
|
||||||
((IClose)this.conductor).Close();
|
((IScreenState)this.conductor).Close();
|
||||||
screen.Verify(x => x.Dispose(), Times.Never);
|
screen.Verify(x => x.Dispose(), Times.Never);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,5 +190,14 @@ namespace StyletUnitTests
|
||||||
Assert.IsInstanceOf<InvalidOperationException>(e.InnerException);
|
Assert.IsInstanceOf<InvalidOperationException>(e.InnerException);
|
||||||
Assert.AreEqual("foo", e.InnerException.Message);
|
Assert.AreEqual("foo", e.InnerException.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ExecuteThrowsIfActionTargetIsDefault()
|
||||||
|
{
|
||||||
|
View.SetActionTarget(this.subject, View.InitialActionTarget);
|
||||||
|
var cmd = new EventAction(this.subject, this.eventInfo.EventHandlerType, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
|
||||||
|
var e = Assert.Throws<TargetInvocationException>(() => cmd.GetDelegate().DynamicInvoke(null, null));
|
||||||
|
Assert.IsInstanceOf<ActionNotSetException>(e.InnerException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,39 +26,39 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryActivateActivatesIActivate()
|
public void TryActivateActivatesIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IActivate>();
|
var screen = new Mock<IScreenState>();
|
||||||
ScreenExtensions.TryActivate(screen.Object);
|
ScreenExtensions.TryActivate(screen.Object);
|
||||||
screen.Verify(x => x.Activate());
|
screen.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryActivateDoesNothingToNonIActivate()
|
public void TryActivateDoesNothingToNonIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IDeactivate>(MockBehavior.Strict);
|
var screen = new Mock<IGuardClose>(MockBehavior.Strict);
|
||||||
ScreenExtensions.TryActivate(screen.Object);
|
ScreenExtensions.TryActivate(screen.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryDeactivateDeactivatesIDeactivate()
|
public void TryDeactivateDeactivatesIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IDeactivate>();
|
var screen = new Mock<IScreenState>();
|
||||||
ScreenExtensions.TryDeactivate(screen.Object);
|
ScreenExtensions.TryDeactivate(screen.Object);
|
||||||
screen.Verify(x => x.Deactivate());
|
screen.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryDeactivateDoesNothingToNonIDeactivate()
|
public void TryDeactivateDoesNothingToNonIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IActivate>(MockBehavior.Strict);
|
var screen = new Mock<IGuardClose>(MockBehavior.Strict);
|
||||||
ScreenExtensions.TryDeactivate(screen.Object);
|
ScreenExtensions.TryDeactivate(screen.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryCloseClosesIClose()
|
public void TryCloseClosesIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IClose>();
|
var screen = new Mock<IScreenState>();
|
||||||
ScreenExtensions.TryClose(screen.Object);
|
ScreenExtensions.TryClose(screen.Object);
|
||||||
screen.Verify(x => x.Close());
|
screen.Verify(x => x.Close());
|
||||||
}
|
}
|
||||||
|
@ -72,35 +72,103 @@ namespace StyletUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TryCloseDoesNothingToNonIClose()
|
public void TryCloseDoesNothingToNonIScreenState()
|
||||||
{
|
{
|
||||||
var screen = new Mock<IActivate>(MockBehavior.Strict);
|
var screen = new Mock<IGuardClose>(MockBehavior.Strict);
|
||||||
ScreenExtensions.TryClose(screen.Object);
|
ScreenExtensions.TryClose(screen.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ActivateWithActivates()
|
||||||
|
{
|
||||||
|
this.child.Object.ActivateWith(this.parent);
|
||||||
|
((IScreenState)this.parent).Activate();
|
||||||
|
this.child.Verify(x => x.Activate());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ActivateWithDoesNotRetainChild()
|
||||||
|
{
|
||||||
|
var child = new Screen();
|
||||||
|
child.ActivateWith(this.parent);
|
||||||
|
|
||||||
|
var weakChild = new WeakReference(child);
|
||||||
|
child = null;
|
||||||
|
GC.Collect();
|
||||||
|
|
||||||
|
((IScreenState)this.parent).Activate();
|
||||||
|
Assert.Null(weakChild.Target);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConductWithActivates()
|
public void ConductWithActivates()
|
||||||
{
|
{
|
||||||
this.child.Object.ConductWith(this.parent);
|
this.child.Object.ConductWith(this.parent);
|
||||||
((IActivate)this.parent).Activate();
|
((IScreenState)this.parent).Activate();
|
||||||
this.child.Verify(x => x.Activate());
|
this.child.Verify(x => x.Activate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DeactivateWithDeactivates()
|
||||||
|
{
|
||||||
|
// Needs to be active....
|
||||||
|
((IScreenState)this.parent).Activate();
|
||||||
|
this.child.Object.DeactivateWith(this.parent);
|
||||||
|
((IScreenState)this.parent).Deactivate();
|
||||||
|
this.child.Verify(x => x.Deactivate());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DeactivateDoesNotRetainChild()
|
||||||
|
{
|
||||||
|
var child = new Screen();
|
||||||
|
child.DeactivateWith(this.parent);
|
||||||
|
|
||||||
|
var weakChild = new WeakReference(child);
|
||||||
|
child = null;
|
||||||
|
GC.Collect();
|
||||||
|
|
||||||
|
((IScreenState)this.parent).Deactivate();
|
||||||
|
Assert.Null(weakChild.Target);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConductWithDeactivates()
|
public void ConductWithDeactivates()
|
||||||
{
|
{
|
||||||
// Needs to be active....
|
// Needs to be active....
|
||||||
((IActivate)this.parent).Activate();
|
((IScreenState)this.parent).Activate();
|
||||||
this.child.Object.ConductWith(this.parent);
|
this.child.Object.ConductWith(this.parent);
|
||||||
((IDeactivate)this.parent).Deactivate();
|
((IScreenState)this.parent).Deactivate();
|
||||||
this.child.Verify(x => x.Deactivate());
|
this.child.Verify(x => x.Deactivate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CloseWithCloses()
|
||||||
|
{
|
||||||
|
this.child.Object.CloseWith(this.parent);
|
||||||
|
((IScreenState)this.parent).Close();
|
||||||
|
this.child.Verify(x => x.Close());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CloseWithDoesNotRetain()
|
||||||
|
{
|
||||||
|
var child = new Screen();
|
||||||
|
child.CloseWith(this.parent);
|
||||||
|
|
||||||
|
var weakChild = new WeakReference(child);
|
||||||
|
child = null;
|
||||||
|
GC.Collect();
|
||||||
|
|
||||||
|
((IScreenState)this.parent).Close();
|
||||||
|
Assert.Null(weakChild.Target);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConductWithCloses()
|
public void ConductWithCloses()
|
||||||
{
|
{
|
||||||
this.child.Object.ConductWith(this.parent);
|
this.child.Object.ConductWith(this.parent);
|
||||||
((IClose)this.parent).Close();
|
((IScreenState)this.parent).Close();
|
||||||
this.child.Verify(x => x.Close());
|
this.child.Verify(x => x.Close());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,11 @@ namespace StyletUnitTests
|
||||||
public MyScreen() { }
|
public MyScreen() { }
|
||||||
public MyScreen(IModelValidator validator) : base(validator) { }
|
public MyScreen(IModelValidator validator) : base(validator) { }
|
||||||
|
|
||||||
|
public new void SetState(ScreenState newState, Action<ScreenState, ScreenState> changedHandler)
|
||||||
|
{
|
||||||
|
base.SetState(newState, changedHandler);
|
||||||
|
}
|
||||||
|
|
||||||
public bool OnActivateCalled;
|
public bool OnActivateCalled;
|
||||||
protected override void OnActivate()
|
protected override void OnActivate()
|
||||||
{
|
{
|
||||||
|
@ -92,7 +97,7 @@ namespace StyletUnitTests
|
||||||
[Test]
|
[Test]
|
||||||
public void ActivateActivatesIfNotAlreadyActive()
|
public void ActivateActivatesIfNotAlreadyActive()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
Assert.IsTrue(this.screen.IsActive);
|
Assert.IsTrue(this.screen.IsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,41 +106,81 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
bool fired = false;
|
bool fired = false;
|
||||||
this.screen.Activated += (o, e) => fired = true;
|
this.screen.Activated += (o, e) => fired = true;
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
Assert.IsTrue(fired);
|
Assert.IsTrue(fired);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ActivateCallsOnActivate()
|
public void ActivateCallsOnActivate()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
Assert.IsTrue(this.screen.OnActivateCalled);
|
Assert.IsTrue(this.screen.OnActivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DoubleActivationDoesntActivate()
|
public void DoubleActivationDoesntActivate()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
this.screen.OnActivateCalled = false;
|
this.screen.OnActivateCalled = false;
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
Assert.IsFalse(this.screen.OnActivateCalled);
|
Assert.IsFalse(this.screen.OnActivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void InitialActivationCallsOnInitialActivate()
|
public void InitialActivationCallsOnInitialActivate()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
this.screen.OnInitialActivateCalled = false;
|
this.screen.OnInitialActivateCalled = false;
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
Assert.IsFalse(this.screen.OnInitialActivateCalled);
|
Assert.IsFalse(this.screen.OnInitialActivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ActivateFiresCorrectEvents()
|
||||||
|
{
|
||||||
|
this.screen.SetState(ScreenState.Deactivated, (n, o) => { });
|
||||||
|
|
||||||
|
var changedEventArgs = new List<ScreenStateChangedEventArgs>();
|
||||||
|
this.screen.StateChanged += (o, e) => changedEventArgs.Add(e);
|
||||||
|
var activatedEventArgs = new List<ActivationEventArgs>();
|
||||||
|
this.screen.Activated += (o, e) => activatedEventArgs.Add(e);
|
||||||
|
|
||||||
|
((IScreenState)this.screen).Activate();
|
||||||
|
|
||||||
|
Assert.AreEqual(1, changedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Active, changedEventArgs[0].NewState);
|
||||||
|
Assert.AreEqual(ScreenState.Deactivated, changedEventArgs[0].PreviousState);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, activatedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Deactivated, activatedEventArgs[0].PreviousState);
|
||||||
|
Assert.IsFalse(activatedEventArgs[0].IsInitialActivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void InitialActivateFiresCorrectEvents()
|
||||||
|
{
|
||||||
|
var changedEventArgs = new List<ScreenStateChangedEventArgs>();
|
||||||
|
this.screen.StateChanged += (o, e) => changedEventArgs.Add(e);
|
||||||
|
var activatedEventArgs = new List<ActivationEventArgs>();
|
||||||
|
this.screen.Activated += (o, e) => activatedEventArgs.Add(e);
|
||||||
|
|
||||||
|
((IScreenState)this.screen).Activate();
|
||||||
|
|
||||||
|
Assert.AreEqual(1, changedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Active, changedEventArgs[0].NewState);
|
||||||
|
Assert.AreEqual(ScreenState.Initial, changedEventArgs[0].PreviousState);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, activatedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Initial, activatedEventArgs[0].PreviousState);
|
||||||
|
Assert.IsTrue(activatedEventArgs[0].IsInitialActivate);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DeactivateDeactivates()
|
public void DeactivateDeactivates()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate(); ;
|
((IScreenState)this.screen).Activate(); ;
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
Assert.IsFalse(this.screen.IsActive);
|
Assert.IsFalse(this.screen.IsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,34 +189,54 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
bool fired = false;
|
bool fired = false;
|
||||||
this.screen.Deactivated += (o, e) => fired = true;
|
this.screen.Deactivated += (o, e) => fired = true;
|
||||||
((IActivate)this.screen).Activate(); ;
|
((IScreenState)this.screen).Activate(); ;
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
Assert.IsTrue(fired);
|
Assert.IsTrue(fired);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DeactivateCallsOnDeactivate()
|
public void DeactivateCallsOnDeactivate()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
Assert.IsTrue(this.screen.OnDeactivateCalled);
|
Assert.IsTrue(this.screen.OnDeactivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DoubleDeactivationDoesntDeactivate()
|
public void DoubleDeactivationDoesntDeactivate()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
this.screen.OnDeactivateCalled = false;
|
this.screen.OnDeactivateCalled = false;
|
||||||
((IDeactivate)this.screen).Deactivate();
|
((IScreenState)this.screen).Deactivate();
|
||||||
Assert.IsFalse(this.screen.OnDeactivateCalled);
|
Assert.IsFalse(this.screen.OnDeactivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DeactivateFiresCorrectEvents()
|
||||||
|
{
|
||||||
|
this.screen.SetState(ScreenState.Active, (n, o) => { });
|
||||||
|
|
||||||
|
var changedEventArgs = new List<ScreenStateChangedEventArgs>();
|
||||||
|
this.screen.StateChanged += (o, e) => changedEventArgs.Add(e);
|
||||||
|
var deactivationEventArgs = new List<DeactivationEventArgs>();
|
||||||
|
this.screen.Deactivated += (o, e) => deactivationEventArgs.Add(e);
|
||||||
|
|
||||||
|
((IScreenState)this.screen).Deactivate();
|
||||||
|
|
||||||
|
Assert.AreEqual(1, changedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Deactivated, changedEventArgs[0].NewState);
|
||||||
|
Assert.AreEqual(ScreenState.Active, changedEventArgs[0].PreviousState);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, deactivationEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Active, deactivationEventArgs[0].PreviousState);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CloseDeactivates()
|
public void CloseDeactivates()
|
||||||
{
|
{
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsTrue(this.screen.OnDeactivateCalled);
|
Assert.IsTrue(this.screen.OnDeactivateCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +244,7 @@ namespace StyletUnitTests
|
||||||
public void CloseClearsView()
|
public void CloseClearsView()
|
||||||
{
|
{
|
||||||
((IViewAware)this.screen).AttachView(new UIElement());
|
((IViewAware)this.screen).AttachView(new UIElement());
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsNull(this.screen.View);
|
Assert.IsNull(this.screen.View);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,33 +253,53 @@ namespace StyletUnitTests
|
||||||
{
|
{
|
||||||
bool fired = false;
|
bool fired = false;
|
||||||
this.screen.Closed += (o, e) => fired = true;
|
this.screen.Closed += (o, e) => fired = true;
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsTrue(fired);
|
Assert.IsTrue(fired);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CloseCallsOnClose()
|
public void CloseCallsOnClose()
|
||||||
{
|
{
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsTrue(this.screen.OnCloseCalled);
|
Assert.IsTrue(this.screen.OnCloseCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DoubleCloseDoesNotClose()
|
public void DoubleCloseDoesNotClose()
|
||||||
{
|
{
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
this.screen.OnCloseCalled = false;
|
this.screen.OnCloseCalled = false;
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsFalse(this.screen.OnCloseCalled);
|
Assert.IsFalse(this.screen.OnCloseCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CloseFiresCorrectEvents()
|
||||||
|
{
|
||||||
|
this.screen.SetState(ScreenState.Deactivated, (n, o) => { });
|
||||||
|
|
||||||
|
var changedEventArgs = new List<ScreenStateChangedEventArgs>();
|
||||||
|
this.screen.StateChanged += (o, e) => changedEventArgs.Add(e);
|
||||||
|
var closeEventArgs = new List<CloseEventArgs>();
|
||||||
|
this.screen.Closed += (o, e) => closeEventArgs.Add(e);
|
||||||
|
|
||||||
|
((IScreenState)this.screen).Close();
|
||||||
|
|
||||||
|
Assert.AreEqual(1, changedEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Closed, changedEventArgs[0].NewState);
|
||||||
|
Assert.AreEqual(ScreenState.Deactivated, changedEventArgs[0].PreviousState);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, closeEventArgs.Count);
|
||||||
|
Assert.AreEqual(ScreenState.Deactivated, closeEventArgs[0].PreviousState);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ActivatingAllowsScreenToBeClosedAgain()
|
public void ActivatingAllowsScreenToBeClosedAgain()
|
||||||
{
|
{
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
this.screen.OnCloseCalled = false;
|
this.screen.OnCloseCalled = false;
|
||||||
((IActivate)this.screen).Activate();
|
((IScreenState)this.screen).Activate();
|
||||||
((IClose)this.screen).Close();
|
((IScreenState)this.screen).Close();
|
||||||
Assert.IsTrue(this.screen.OnCloseCalled);
|
Assert.IsTrue(this.screen.OnCloseCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,10 +101,41 @@ namespace StyletUnitTests
|
||||||
this.windowManager.CreateWindow(model, false);
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
var e = window.GetBindingExpression(Window.TitleProperty);
|
var e = window.GetBindingExpression(Window.TitleProperty);
|
||||||
|
Assert.NotNull(e);
|
||||||
Assert.AreEqual(BindingMode.TwoWay, e.ParentBinding.Mode);
|
Assert.AreEqual(BindingMode.TwoWay, e.ParentBinding.Mode);
|
||||||
Assert.AreEqual("DisplayName", e.ParentBinding.Path.Path);
|
Assert.AreEqual("DisplayName", e.ParentBinding.Path.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowDoesNotSetUpTitleBindingIfTitleHasAValueAlready()
|
||||||
|
{
|
||||||
|
var model = new Screen();
|
||||||
|
var window = new Window();
|
||||||
|
window.Title = "Foo";
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
var e = window.GetBindingExpression(Window.TitleProperty);
|
||||||
|
Assert.IsNull(e);
|
||||||
|
Assert.AreEqual("Foo", window.Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowDoesNotSetUpTitleBindingIfTitleHasABindingAlready()
|
||||||
|
{
|
||||||
|
var model = new Screen();
|
||||||
|
var window = new Window();
|
||||||
|
var binding = new Binding("Test") { Mode = BindingMode.TwoWay };
|
||||||
|
window.SetBinding(Window.TitleProperty, binding);
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
var e = window.GetBindingExpression(Window.TitleProperty);
|
||||||
|
Assert.AreEqual("Test", e.ParentBinding.Path.Path);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CreateWindowActivatesViewModel()
|
public void CreateWindowActivatesViewModel()
|
||||||
{
|
{
|
||||||
|
@ -283,5 +314,56 @@ namespace StyletUnitTests
|
||||||
|
|
||||||
this.messageBoxViewModel.Verify(x => x.Setup("text", "title", MessageBoxButton.OKCancel, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxResult.Cancel, MessageBoxOptions.RtlReading, null));
|
this.messageBoxViewModel.Verify(x => x.Setup("text", "title", MessageBoxButton.OKCancel, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxResult.Cancel, MessageBoxOptions.RtlReading, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowSetsWindowStartupLocationToCenterScreenIfThereIsNoOwnerAndItHasNotBeenSetAlready()
|
||||||
|
{
|
||||||
|
var model = new object();
|
||||||
|
var window = new Window();
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
Assert.AreEqual(WindowStartupLocation.CenterScreen, window.WindowStartupLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowDoesNotSetStartupLocationIfItIsNotManual()
|
||||||
|
{
|
||||||
|
var model = new object();
|
||||||
|
var window = new Window();
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
Assert.AreEqual(WindowStartupLocation.CenterOwner, window.WindowStartupLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowDoesNotSetStartupLocationIfLeftSet()
|
||||||
|
{
|
||||||
|
var model = new object();
|
||||||
|
var window = new Window();
|
||||||
|
window.Left = 1;
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
Assert.AreEqual(WindowStartupLocation.Manual, window.WindowStartupLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateWindowDoesNotSetStartupLocationIfTopSet()
|
||||||
|
{
|
||||||
|
var model = new object();
|
||||||
|
var window = new Window();
|
||||||
|
window.Top = 1;
|
||||||
|
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||||
|
|
||||||
|
this.windowManager.CreateWindow(model, false);
|
||||||
|
|
||||||
|
Assert.AreEqual(WindowStartupLocation.Manual, window.WindowStartupLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue