/// <summary>
        /// WhenLoaded allows you to register a Func to be called OnViewLoaded.
        /// </summary>
        /// <param name="item">Object that supports loading.</param>
        /// <param name="block">
        /// The method to be called when the corresponding View is loaded.
        /// It returns a list of Disposables that will be cleaned up when the View is unloaded.
        /// </param>
        /// <param name="view">
        /// The IViewFor will ordinarily also host the View Model, but in the event it is not,
        /// a class implementing <see cref="IViewFor&lt;T&gt;" /> can be supplied here.
        /// </param>
        /// <returns>A Disposable that cleans up this registration.</returns>
        public static IDisposable WhenLoaded <T>(this IViewFor <T> item, Func <IEnumerable <IDisposable> > block, IViewFor <T> view) where T : class
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            var loadedFetcher = _loadedFetcherCache.Get(item.GetType());

            if (loadedFetcher == null)
            {
                throw new ArgumentException($"Don't know how to detect when {item.GetType().FullName} is loaded/unloaded, you may need to implement {nameof(ILoadedForViewFetcher)}");
            }

            var viewEvents = loadedFetcher.GetLoadedForView(item);

            var vmDisposable = Disposable.Empty;

            if ((view ?? item) is IViewFor v)
            {
                vmDisposable = HandleViewModelOnViewLoaded(v, viewEvents);
            }

            var viewDisposable =
                typeof(IActivate).IsAssignableFrom(typeof(T)) ?
                HandleViewOnActivatedAndLoaded((view ?? item), block, viewEvents) :
                HandleViewOnLoaded(block, viewEvents);

            return(new CompositeDisposable(vmDisposable, viewDisposable));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets a Type from the specified type name.
        /// Uses a cache to avoid having to use Reflection every time.
        /// </summary>
        /// <param name="type">The name of the type.</param>
        /// <param name="throwOnFailure">If we should throw an exception if the type can't be found.</param>
        /// <returns>The type that was found or null.</returns>
        /// <exception cref="TypeLoadException">If we were unable to find the type.</exception>
        public static Type ReallyFindType(string type, bool throwOnFailure)
        {
            Type ret = typeCache.Get(type);

            if (ret != null || !throwOnFailure)
            {
                return(ret);
            }

            throw new TypeLoadException();
        }
        /// <inheritdoc/>
        public bool TryConvert(object from, Type toType, object conversionHint, out object result)
        {
            Contract.Requires(toType != null);

            var mi = _referenceCastCache.Get(toType);

            try
            {
                result = mi.Invoke(null, new[] { from, toType });
            }
            catch (Exception ex)
            {
                _logger.LogInformation(from, $"Couldn't convert from {from.GetType()} to {toType}\n{ex}\n{ex.Message}");
                result = null;
                return(false);
            }

            return(true);
        }
        public static IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter)
        {
            var type = target.GetType();

            var binder = _bindCommandCache.Get(type);

            if (binder == null)
            {
                throw new Exception($"Couldn't find a Command Binder for {type.FullName}");
            }

            var ret = binder.BindCommandToObject(command, target, commandParameter);

            if (ret == null)
            {
                throw new Exception($"Couldn't bind Command Binder for {type.FullName}");
            }

            return(ret);
        }
        public static IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter, string eventName)
        {
            var type   = target.GetType();
            var binder = _bindCommandEventCache.Get(type);

            if (binder == null)
            {
                throw new Exception($"Couldn't find a Command Binder for {type.FullName} and event {eventName}");
            }

            var eventArgsType = Reflection.GetEventArgsTypeForEvent(type, eventName);
            var mi            = binder.GetType().GetTypeInfo().DeclaredMethods.First(x => x.Name == "BindCommandToObject" && x.IsGenericMethod);

            mi = mi.MakeGenericMethod(new[] { eventArgsType });

            var ret = (IDisposable)mi.Invoke(binder, new[] { command, target, commandParameter, eventName });

            if (ret == null)
            {
                throw new Exception($"Couldn't bind Command Binder for {type.FullName} and event {eventName}");
            }

            return(ret);
        }