public WindowConductor(Window window, object viewModel) { this.window = window; this.viewModel = viewModel; // They won't be able to request a close unless they implement IChild anyway... var viewModelAsChild = this.viewModel as IChild; if (viewModelAsChild != null) { viewModelAsChild.Parent = this; } ScreenExtensions.TryActivate(this.viewModel); var viewModelAsScreenState = this.viewModel as IScreenState; if (viewModelAsScreenState != null) { window.StateChanged += this.WindowStateChanged; window.Closed += this.WindowClosed; } if (this.viewModel is IGuardClose) { window.Closing += this.WindowClosing; } }
/// <summary> /// Close was requested by the child /// </summary> /// <param name="item">Item to close</param> /// <param name="dialogResult">DialogResult to close with, if it's a dialog</param> async void IChildDelegate.CloseItem(object item, bool?dialogResult) { if (item != this.viewModel) { logger.Warn("IChildDelegate.CloseItem called with item {0} which is _not_ our ViewModel {1}", item, this.viewModel); return; } var guardClose = this.viewModel as IGuardClose; if (guardClose != null && !await guardClose.CanCloseAsync()) { logger.Info("Close of ViewModel {0} cancelled because CanCloseAsync returned false", this.viewModel); return; } logger.Info("ViewModel {0} close requested with DialogResult {1} because it called RequestClose", this.viewModel, dialogResult); this.window.StateChanged -= this.WindowStateChanged; this.window.Closed -= this.WindowClosed; this.window.Closing -= this.WindowClosing; // Need to call this after unregistering the event handlers, as it causes the window // to be closed if (dialogResult != null) { this.window.DialogResult = dialogResult; } ScreenExtensions.TryClose(this.viewModel); this.window.Close(); }
/// <summary> /// Switch the active item to the given item /// </summary> /// <param name="newItem">New item to activate</param> /// <param name="closePrevious">Whether the previously-active item should be closed</param> protected virtual void ChangeActiveItem(T newItem, bool closePrevious) { ScreenExtensions.TryDeactivate(this.ActiveItem); if (closePrevious) { this.CloseAndCleanUp(this.ActiveItem, this.DisposeChildren); } this._activeItem = newItem; if (newItem != null) { this.EnsureItem(newItem); if (this.IsActive) { ScreenExtensions.TryActivate(newItem); } else { ScreenExtensions.TryDeactivate(newItem); } } this.NotifyOfPropertyChange("ActiveItem"); }
/// <summary> /// Deactive the given item /// </summary> /// <param name="item">Item to deactivate</param> public override void DeactivateItem(T item) { if (item != null && item.Equals(this.ActiveItem)) { ScreenExtensions.TryDeactivate(this.ActiveItem); } }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public override void Dispose() { // Don't create the root ViewModel if it doesn't already exist... ScreenExtensions.TryDispose(this._rootViewModel); // Dispose the container last base.Dispose(); }
private void WindowClosed(object sender, EventArgs e) { // Logging was done in the Closing handler this.window.StateChanged -= this.WindowStateChanged; this.window.Closed -= this.WindowClosed; this.window.Closing -= this.WindowClosing; // Not sure this is required ScreenExtensions.TryClose(this.viewModel); }
/// <summary> /// Activate the given item and set it as the ActiveItem, deactivating the previous ActiveItem /// </summary> /// <param name="item">Item to deactivate</param> public override void ActivateItem(T item) { if (item != null && item.Equals(this.ActiveItem)) { if (this.IsActive) { ScreenExtensions.TryActivate(this.ActiveItem); } } else { this.ChangeActiveItem(item, false); } }
private void WindowStateChanged(object sender, EventArgs e) { switch (this.window.WindowState) { case WindowState.Maximized: case WindowState.Normal: logger.Info("Window {0} maximized/restored: activating", this.window); ScreenExtensions.TryActivate(this.viewModel); break; case WindowState.Minimized: logger.Info("Window {0} minimized: deactivating", this.window); ScreenExtensions.TryDeactivate(this.viewModel); break; } }
/// <summary> /// Activate the given item, discarding the previous ActiveItem /// </summary> /// <param name="item">Item to active</param> public override async void ActivateItem(T item) { if (item != null && item.Equals(this.ActiveItem)) { if (this.IsActive) { ScreenExtensions.TryActivate(item); } } else if (await this.CanCloseItem(this.ActiveItem)) { // CanCloseItem is null-safe this.ChangeActiveItem(item, true); } }
/// <summary> /// Close an item, and clear its parent if it's set to the current parent /// </summary> /// <typeparam name="T">Type of conductor</typeparam> /// <param name="parent">Parent</param> /// <param name="item">Item to close and clean up</param> /// <param name="dispose">True to dispose children as well as close them</param> public static void CloseAndCleanUp <T>(this IConductor <T> parent, T item, bool dispose) { ScreenExtensions.TryClose(item); var itemAsChild = item as IChild; if (itemAsChild != null && itemAsChild.Parent == parent) { itemAsChild.Parent = null; } if (dispose) { ScreenExtensions.TryDispose(item); } }
/// <summary> /// Deactive the given item, and choose another item to set as the ActiveItem /// </summary> /// <param name="item">Item to deactivate</param> public override void DeactivateItem(T item) { if (item == null) { return; } if (item.Equals(this.ActiveItem)) { var nextItem = this.DetermineNextItemToActivate(item); this.ChangeActiveItem(nextItem, false); } else { ScreenExtensions.TryDeactivate(item); } }
/// <summary> /// Activate the given item, and add it to the Items collection /// </summary> /// <param name="item">Item to activate</param> public override void ActivateItem(T item) { if (item == null) { return; } this.EnsureItem(item); if (this.IsActive) { ScreenExtensions.TryActivate(item); } else { ScreenExtensions.TryDeactivate(item); } }
/// <summary> /// For each item in a list, set the parent to the current conductor /// </summary> /// <typeparam name="T">Type of conductor</typeparam> /// <param name="parent">Parent to set the items' parent to</param> /// <param name="items">Items to manipulate</param> /// <param name="active">True to active the item, false to deactive it</param> public static void SetParentAndSetActive <T>(this IConductor <T> parent, IEnumerable items, bool active) { foreach (var item in items) { var itemAsChild = item as IChild; if (itemAsChild != null) { itemAsChild.Parent = parent; } if (active) { ScreenExtensions.TryActivate(item); } else { ScreenExtensions.TryDeactivate(item); } } }
/// <summary> /// When we're deactivated, also deactivate the ActiveItem /// </summary> protected override void OnDeactivate() { ScreenExtensions.TryDeactivate(this.ActiveItem); }
/// <summary> /// Deactive the given item /// </summary> /// <param name="item">Item to deactivate</param> public override void DeactivateItem(T item) { ScreenExtensions.TryDeactivate(item); }