Search code examples
silverlightmvvmcaliburncaliburn.micro

Caliburn.Micro and WebServiceResult


I'm looking for the correct version of this class for Caliburn.Micro

public class WebServiceResult : IResult where T : new()

The above signature is from the ContactManager example in the full Caliburn framework. It does not cut and paste directly into a Micro-based project. There are too many missing classes to use this directly. Thoughts? or anyone know of the replacement?


Solution

  • Event though the underlying infrastructure is very different in Caliburn Micro (which is based on System.Windows.Interactivity), the concepts are pretty much the same.

    Here is the CM version:

    public class WebServiceResult<T, K> : IResult
        where T : new()
        where K : EventArgs
    {
    
        readonly static Func<bool> ALWAYS_FALSE_GUARD= () => false;
        readonly static Func<bool> ALWAYS_TRUE_GUARD = () => true;
    
        private readonly Action<K> _callback;
        private readonly Expression<Action<T>> _serviceCall;
    
        private ActionExecutionContext _currentContext;
        private Func<bool> _originalGuard;
    
    
    
    
        public WebServiceResult(Expression<Action<T>> serviceCall)
        { 
            _serviceCall = serviceCall;
        }
    
        public WebServiceResult(Expression<Action<T>> serviceCall, Action<K> callback)
        {
            _serviceCall = serviceCall;
            _callback = callback;
        }
    
        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
    
        public void Execute(ActionExecutionContext context)
        {
            _currentContext = context;
    
            //if you would to disable the control that caused the service to be called, you could do this:
            ChangeAvailability(false);
    
            var lambda = (LambdaExpression)_serviceCall;
            var methodCall = (MethodCallExpression)lambda.Body;
            var eventName = methodCall.Method.Name.Replace("Async", "Completed");
            var eventInfo = typeof(T).GetEvent(eventName);
    
            var service = new T();
    
            eventInfo.AddEventHandler(service, new EventHandler<K>(OnEvent));
    
            _serviceCall.Compile()(service);
        }
    
        public void OnEvent(object sender, K args)
        {
            //re-enable the control that caused the service to be called:
            ChangeAvailability(true);
    
            if (_callback != null)
                _callback(args);
    
            Completed(this, new ResultCompletionEventArgs());
        }
    
    
    
        private void ChangeAvailability(bool isAvailable)
        {
            if (_currentContext == null) return;
    
            if (!isAvailable) {
                _originalGuard = _currentContext.CanExecute;
                _currentContext.CanExecute = ALWAYS_FALSE_GUARD;
            }
            else if (_currentContext.CanExecute == ALWAYS_FALSE_GUARD) {
    
                _currentContext.CanExecute = _originalGuard ?? ALWAYS_TRUE_GUARD;
            }
    
    
            _currentContext.Message.UpdateAvailability();
    
        }
    
    
    }