public IObservable<bool> GetActivationForView(IActivatable view)
        {
            var control = view as Control;
            if (control == null) {
                // Show a friendly warning in the log that this view will never be activated
                this.Log().Warn("Expected a view of type System.Windows.Forms.Control but it is {0}.\r\nYou need to implement your own IActivationForViewFetcher for {0}.", view.GetType());
                return Observable.Empty<bool>();
            }

            // Create an observable stream of booleans
            // true representing the control is active, false representing the control is not active
            // by using DistinctUntilChanged, a control can either be active or not active
            // This should also fix #610 for winforms

            var controlVisible = Observable.FromEventPattern(control, "VisibleChanged").Select(_ => control.Visible);
            var handleDestroyed = Observable.FromEventPattern(control, "HandleDestroyed").Select(_ => false);
            var handleCreated = Observable.FromEventPattern(control, "HandleCreated").Select(_ => true);

            var controlActive = Observable.Merge(controlVisible, handleDestroyed, handleCreated)
                .DistinctUntilChanged();

            

            var form = view as Form;
            if (form != null) {
                var formActive = Observable.FromEventPattern(form, "Closed").Select(_ => false);
                return controlActive.Merge(formActive).DistinctUntilChanged();
            }

            return controlActive;
        }
Exemple #2
0
        /// <summary>
        /// WhenActivated allows you to register a Func to be called when a
        /// View is Activated.
        /// </summary>
        /// <param name="block">The method to be called when the corresponding
        /// View is activated. It returns a list of Disposables that will be
        /// cleaned up when the View is deactivated.</param>
        /// <returns>A Disposable that deactivates this registration.</returns>
        public static IDisposable WhenActivated(this IActivatable This, Func <IEnumerable <IDisposable> > block)
        {
            var activationFetcher = activationFetcherCache.Get(This.GetType());

            if (activationFetcher == null)
            {
                var msg = "Don't know how to detect when {0} is activated/deactivated, you may need to implement IActivationForViewFetcher";
                throw new ArgumentException(String.Format(msg, This.GetType().FullName));
            }

            var activationEvents = activationFetcher.GetActivationForView(This);

            var vmDisposable = Disposable.Empty;

            if (This is IViewFor)
            {
                vmDisposable = handleViewModelActivation(This as IViewFor, activationEvents);
            }

            var viewDisposable = handleViewActivation(block, activationEvents);

            return(new CompositeDisposable(vmDisposable, viewDisposable));
        }
Exemple #3
0
        /// <summary>
        /// WhenActivated allows you to register a Func to be called when a
        /// View is Activated.
        /// </summary>
        /// <param name="this">Object that supports activation.</param>
        /// <param name="block">
        /// The method to be called when the corresponding
        /// View is activated. It returns a list of Disposables that will be
        /// cleaned up when the View is deactivated.
        /// </param>
        /// <param name="view">
        /// The IActivatable will ordinarily also host the View
        /// Model, but in the event it is not, a class implementing <see cref="IViewFor" />
        /// can be supplied here.
        /// </param>
        /// <returns>A Disposable that deactivates this registration.</returns>
        public static IDisposable WhenActivated(this IActivatable @this, Func <IEnumerable <IDisposable> > block, IViewFor view)
        {
            var activationFetcher = activationFetcherCache.Get(@this.GetType());

            if (activationFetcher == null)
            {
                const string msg = "Don't know how to detect when {0} is activated/deactivated, you may need to implement IActivationForViewFetcher";
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, msg, @this.GetType().FullName));
            }

            var activationEvents = activationFetcher.GetActivationForView(@this);

            var vmDisposable = Disposable.Empty;

            if ((view ?? @this) is IViewFor v)
            {
                vmDisposable = HandleViewModelActivation(v, activationEvents);
            }

            var viewDisposable = HandleViewActivation(block, activationEvents);

            return(new CompositeDisposable(vmDisposable, viewDisposable));
        }
        /// <inheritdoc/>
        public IObservable <bool> GetActivationForView(IActivatable view)
        {
            // Startup: Control.HandleCreated > Control.BindingContextChanged > Form.Load > Control.VisibleChanged > Form.Activated > Form.Shown
            // Shutdown: Form.Closing > Form.FormClosing > Form.Closed > Form.FormClosed > Form.Deactivate
            // https://docs.microsoft.com/en-us/dotnet/framework/winforms/order-of-events-in-windows-forms
            if (view is Control control)
            {
                if (GetCachedIsDesignMode(control))
                {
                    return(Observable <bool> .Empty);
                }

                var handleDestroyed = Observable.FromEventPattern(control, "HandleDestroyed").Select(_ => false);
                var handleCreated   = Observable.FromEventPattern(control, "HandleCreated").Select(_ => true);
                var visibleChanged  = Observable.FromEventPattern(control, "VisibleChanged").Select(_ => control.Visible);

                var controlActivation = Observable.Merge(handleDestroyed, handleCreated, visibleChanged)
                                        .DistinctUntilChanged();

                if (view is Form form)
                {
                    var formClosed = Observable.FromEventPattern(form, "FormClosed").Select(_ => false);
                    controlActivation = controlActivation.Merge(formClosed)
                                        .DistinctUntilChanged();
                }

                return(controlActivation);
            }

            // Show a friendly warning in the log that this view will never be activated
            this.Log().Warn(
                CultureInfo.InvariantCulture,
                "Expected a view of type System.Windows.Forms.Control but it is {0}.\r\nYou need to implement your own IActivationForViewFetcher for {0}.",
                view?.GetType());

            return(Observable <bool> .Empty);
        }
Exemple #5
0
        public IObservable <bool> GetActivationForView(IActivatable view)
        {
            var control = view as Control;

            if (control == null)
            {
                // Show a friendly warning in the log that this view will never be activated
                this.Log().Warn("Expected a view of type System.Windows.Forms.Control but it is {0}.\r\nYou need to implement your own IActivationForViewFetcher for {0}.", view.GetType());
                return(Observable <bool> .Empty);
            }

            // Create an observable stream of booleans
            // true representing the control is active, false representing the control is not active
            // by using DistinctUntilChanged, a control can either be active or not active
            // This should also fix #610 for winforms

            var controlVisible  = Observable.FromEventPattern(control, "VisibleChanged").Select(_ => control.Visible);
            var handleDestroyed = Observable.FromEventPattern(control, "HandleDestroyed").Select(_ => false);
            var handleCreated   = Observable.FromEventPattern(control, "HandleCreated").Select(_ => true);

            var controlActive = Observable.Merge(controlVisible, handleDestroyed, handleCreated)
                                .DistinctUntilChanged();



            var form = view as Form;

            if (form != null)
            {
                var formActive = Observable.FromEventPattern(form, "Closed").Select(_ => false);
                return(controlActive.Merge(formActive).DistinctUntilChanged());
            }

            return(controlActive);
        }