protected void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }

            if (PropertyInfo == null)
            {
                return;
            }

            var currentValue = PropertyInfo.GetValue(Source, PropertyIndexParameters());
            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
示例#2
0
        protected void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }

            if (PropertyInfo == null)
            {
                return;
            }

            var currentValue = PropertyInfo.GetValue(Source, PropertyIndexParameters());

            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding          = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
        protected void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }

            if (NotifyChange == null)
            {
                return;
            }

            var currentValue = NotifyChange.Value;
            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
        public ObservableMvxSourceBinding(IObservable<object> source, List<MvxPropertyToken> remainingTokens)
        {
            this._sourceType = source is BindingToObservableWrapper
                                   ? ((BindingToObservableWrapper)source).SourceType.GetTypeInfo().GenericTypeArguments[0]
                                   : typeof(object);

            this._subscription = source
                .ToWeakObservable()
                .Subscribe(value =>
                {
                    this._currentValue = value;

                    if (this._currentSubBinding != null)
                    {
                        this._currentSubBinding.Dispose();
                        this._currentSubBinding = null;
                    }

                    if ((remainingTokens != null) && (remainingTokens.Count > 0))
                        this._currentSubBinding = MvxBindingSingletonCache.Instance.SourceBindingFactory.CreateBinding(value, remainingTokens);

                    var changed = this.Changed;
                    if (changed != null)
                        changed(this, EventArgs.Empty);
                });
        }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken,
                                     List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return false;
            }

            var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;
            if (propertyNameToken == null)
            {
                result = null;
                return false;
            }

            var fieldInfo = FindFieldInfo(source, propertyNameToken.PropertyName);

            if (fieldInfo == null)
            {
                result = null;
                return false;
            }

            if (typeof (INotifyChange).IsAssignableFrom(fieldInfo.FieldType))
            {
                return TryCreateNotifyChangeBinding(source, remainingTokens, out result, fieldInfo, propertyNameToken);
            }

            return TryCreateFieldInfoBinding(source, remainingTokens, out result, fieldInfo);
        }
示例#6
0
        private void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding          = null;
            }

            if (PropertyInfo == null)
            {
                return;
            }

            var currentValue = PropertyInfo.GetValue(Source, null);

            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding          = SourceBindingFactory.CreateBinding(currentValue, _childPropertyNames);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
示例#7
0
        private static void UpdateSourceFromTarget(MvxBindingRequest bindingRequest, IMvxSourceBinding sourceBinding, object value)
        {
            try
            {
                if (bindingRequest.Description.Converter != null)
                {
                    value =
                        bindingRequest.Description.Converter.ConvertBack(value,
                                                                         sourceBinding.SourceType,
                                                                         bindingRequest.Description.ConverterParameter,
                                                                         CultureInfo.CurrentUICulture);
                }
                sourceBinding.SetValue(value);
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception exception)
            {
                MvxBindingTrace.Trace(
                    MvxTraceLevel.Error,

                    "Problem seen during binding execution for {0} - problem {1}",
                    bindingRequest.ToString(),
                    exception.ToLongString());
            }
        }
        protected void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }

            if (NotifyChange == null)
            {
                return;
            }

            var currentValue = NotifyChange.Value;

            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding          = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken,
                                     List <MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return(false);
            }

            var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;

            if (propertyNameToken == null)
            {
                result = null;
                return(false);
            }

            var fieldInfo = FindFieldInfo(source, propertyNameToken.PropertyName);

            if (fieldInfo == null)
            {
                result = null;
                return(false);
            }

            if (typeof(INotifyChange).IsAssignableFrom(fieldInfo.FieldType))
            {
                return(TryCreateNotifyChangeBinding(source, remainingTokens, out result, fieldInfo, propertyNameToken));
            }

            return(TryCreateFieldInfoBinding(source, remainingTokens, out result, fieldInfo));
        }
 protected virtual void ClearSourceBinding()
 {
     if (_sourceBinding != null)
     {
         _sourceBinding.Dispose();
         _sourceBinding = null;
     }
 }
 protected virtual void ClearSourceBinding()
 {
     if (_sourceBinding != null)
     {
         _sourceBinding.Dispose();
         _sourceBinding = null;
     }
 }
示例#12
0
 private void ClearSourceBinding()
 {
     if (_sourceBinding != null)
     {
         _sourceBinding.Dispose();
         _sourceBinding = null;
     }
 }
 private void ClearPathSourceBinding()
 {
     if (_sourceBinding != null)
     {
         _sourceBinding.Changed -= SourceBindingOnChanged;
         _sourceBinding.Dispose();
         _sourceBinding = null;
     }
 }
示例#14
0
        public ObservableMvxSourceBinding(IObservable <T> source, Type sourceType, IMvxMainThreadDispatcher mainThreadDispatcher, IList <MvxPropertyToken> remainingTokens)
        {
            Contract.Requires(source != null);
            Contract.Requires(sourceType != null);

            this._sourceType = sourceType;

            if (mainThreadDispatcher != null)
            {
                source = source.ObserveOn(mainThreadDispatcher);
            }

            this._sourceSubscription = source
                                       .Subscribe(value =>
            {
                this._currentValue = value;

                if (this._currentSubBinding != null)
                {
                    this._currentSubBinding.Dispose();
                    this._currentSubBinding = null;
                }

                if (this._currentSubBindingSubscription != null)
                {
                    this._currentSubBindingSubscription.Dispose();
                    this._currentSubBindingSubscription = null;
                }

                IMvxSourceBinding newSubBinding = null;
                if ((remainingTokens != null) && (remainingTokens.Count > 0))
                {
                    newSubBinding = MvxSingleton <IMvxBindingSingletonCache> .Instance.SourceBindingFactory.CreateBinding(value, remainingTokens);
                }

                var subBindingObservable = (newSubBinding != null)
                        ? Observable
                                           .Return <object>(null)
                                           .Concat(Observable
                                                   .FromEventPattern(eh => newSubBinding.Changed += eh, eh => newSubBinding.Changed -= eh))
                                           .Select(x => newSubBinding.GetValue())
                                           .Select(x => (x as IObservable <object>) ?? Observable.Return(x))
                                           .Switch()
                        : Observable.Return <object>(null);

                this._currentSubBinding = newSubBinding;

                this._currentSubBindingSubscription = subBindingObservable.Subscribe((value2 =>
                {
                    var changed2 = this.Changed;
                    if (changed2 != null)
                    {
                        changed2(this, EventArgs.Empty);
                    }
                }));
            });
        }
示例#15
0
 private void ClearPathSourceBinding()
 {
     if (this._sourceBinding != null)
     {
         this._sourceBinding.Changed -= this.SourceBindingOnChanged;
         this._sourceBinding.Dispose();
         this._sourceBinding = null;
     }
 }
示例#16
0
 //TODO: optim: dont recreate the source binding on each datacontext change, as SourcePropertyPath does not change.
 //TODO: optim: don't subscribe to the Changed event if the binding mode does not need it.
 protected override void OnDataContextChanged()
 {
     this.ClearPathSourceBinding();
     this._sourceBinding = this.SourceBindingFactory.CreateBinding(this.DataContext, this.Description.SourcePropertyPath);
     if (this._sourceBinding != null)
     {
         this._sourceBinding.Changed += this.SourceBindingOnChanged;
     }
     base.OnDataContextChanged();
 }
示例#17
0
 //TODO: optim: dont recreate the source binding on each datacontext change, as SourcePropertyPath does not change.
 //TODO: optim: don't subscribe to the Changed event if the binding mode does not need it.
 protected override void OnDataContextChanged()
 {
     ClearPathSourceBinding();
     _sourceBinding = SourceBindingFactory.CreateBinding(DataContext, Description.SourcePropertyPath);
     if (_sourceBinding != null)
     {
         _sourceBinding.Changed += SourceBindingOnChanged;
     }
     base.OnDataContextChanged();
 }
        private IMvxSourceBinding Check(IMvxSourceBinding binding)
        {
            if (typeof(IObservable<object>).GetTypeInfo().IsAssignableFrom(binding.SourceType.GetTypeInfo()))
            {
                return new ObservableMvxSourceBinding(
                    new BindingToObservableWrapper(binding), null);
            }

            return binding;
        }
        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing && _currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }

            base.Dispose(isDisposing);
        }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken, List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return false;
            }

            result = remainingTokens.Count == 0 ? this.CreateLeafBinding(source, currentToken) : this.CreateChainedBinding(source, currentToken, remainingTokens);
            return result != null;
        }
示例#21
0
        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                if (_currentChildBinding != null)
                {
                    _currentChildBinding.Dispose();
                    _currentChildBinding = null;
                }
            }

            base.Dispose(isDisposing);
        }
 protected bool TryCreateFieldInfoBinding(object source, List <MvxPropertyToken> remainingTokens,
                                          out IMvxSourceBinding result, FieldInfo fieldInfo)
 {
     if (remainingTokens.Any())
     {
         result = new MvxChainedFieldSourceBinding(source, fieldInfo, remainingTokens);
     }
     else
     {
         result = new MvxLeafFieldSourceBinding(source, fieldInfo);
     }
     return(true);
 }
        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                if (_currentChildBinding != null)
                {
                    _currentChildBinding.Dispose();
                    _currentChildBinding = null;
                }
            }

            base.Dispose(isDisposing);
        }
 protected bool TryCreateFieldInfoBinding(object source, List<MvxPropertyToken> remainingTokens,
                                          out IMvxSourceBinding result, FieldInfo fieldInfo)
 {
     if (remainingTokens.Any())
     {
         result = new MvxChainedFieldSourceBinding(source, fieldInfo, remainingTokens);
     }
     else
     {
         result = new MvxLeafFieldSourceBinding(source, fieldInfo);
     }
     return true;
 }
        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                if (this._currentChildBinding != null)
                {
                    this._currentChildBinding.Changed -= this.ChildSourceBindingChanged;
                    this._currentChildBinding.Dispose();
                    this._currentChildBinding = null;
                }
            }

            base.Dispose(isDisposing);
        }
        protected bool TryCreateBindingFromExtensions(object source, MvxPropertyToken propertyToken,
                                            List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            foreach (var extension in _extensions)
            {
                if (extension.TryCreateBinding(source, propertyToken, remainingTokens, out result))
                {
                    return true;
                }
            }

            result = null;
            return false;
        }
        protected override void Dispose(bool isDisposing)
        {
            if (isDisposing)
            {
                if (this._currentChildBinding != null)
                {
                    this._currentChildBinding.Changed -= this.ChildSourceBindingChanged;
                    this._currentChildBinding.Dispose();
                    this._currentChildBinding = null;
                }
            }

            base.Dispose(isDisposing);
        }
        private void CreateSourceBinding(object source)
        {
            _dataContext = source;
            _sourceBinding = SourceBindingFactory.CreateBinding(source, _bindingDescription.SourcePropertyPath);

            if (NeedToObserveSourceChanges)
                _sourceBinding.Changed += (sender, args) => UpdateTargetFromSource(args.IsAvailable, args.Value);

            if (NeedToUpdateTargetOnBind)
            {
                // note that we expect Bind to be called on the UI thread - so no need to use RunOnUIThread here
                object currentValue;
                bool currentIsAvailable = _sourceBinding.TryGetValue(out currentValue);
                UpdateTargetFromSource(currentIsAvailable, currentValue);
            }
        }
        private void CreateSourceBinding(object source)
        {
            _dataContext   = source;
            _sourceBinding = SourceBindingFactory.CreateBinding(source, _bindingDescription.SourcePropertyPath);

            if (NeedToObserveSourceChanges)
            {
                _sourceBinding.Changed += (sender, args) => UpdateTargetFromSource(args.IsAvailable, args.Value);
            }

            if (NeedToUpdateTargetOnBind)
            {
                // note that we expect Bind to be called on the UI thread - so no need to use RunOnUIThread here
                object currentValue;
                bool   currentIsAvailable = _sourceBinding.TryGetValue(out currentValue);
                UpdateTargetFromSource(currentIsAvailable, currentValue);
            }
        }
        public bool TryCreateBinding(object source, MvxPropertyToken propertyToken, List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            var observable = source as IObservable<object>;

            if (observable != null)
            {
                var list = new List<MvxPropertyToken>();

                if (!(propertyToken is MvxEmptyPropertyToken))
                    list.Add(propertyToken);

                list.AddRange(remainingTokens);

                result = new ObservableMvxSourceBinding(observable, list);
                return true;
            }

            result = null;
            return false;
        }
 private void UpdateChildBinding()
 {
     if (_currentChildBinding != null)
     {
         _currentChildBinding.Changed -= ChildSourceBindingChanged;
         _currentChildBinding.Dispose();
         _currentChildBinding = null;
     }
     var currentValue = FieldInfo.GetValue(Source);
     if (currentValue == null)
     {
         // value will be missing... so end consumer will need to use fallback values
         return;
     }
     else
     {
         _currentChildBinding = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
         _currentChildBinding.Changed += ChildSourceBindingChanged;
     }
 }
示例#32
0
        private void UpdateChildBinding()
        {
            if (_currentChildBinding != null)
            {
                _currentChildBinding.Changed -= ChildSourceBindingChanged;
                _currentChildBinding.Dispose();
                _currentChildBinding = null;
            }
            var currentValue = FieldInfo.GetValue(Source);

            if (currentValue == null)
            {
                // value will be missing... so end consumer will need to use fallback values
                return;
            }
            else
            {
                _currentChildBinding          = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
                _currentChildBinding.Changed += ChildSourceBindingChanged;
            }
        }
        protected bool TryCreateNotifyChangeBinding(object source, List<MvxPropertyToken> remainingTokens,
                                                    out IMvxSourceBinding result,
                                                    FieldInfo fieldInfo, MvxPropertyNamePropertyToken propertyNameToken)
        {
            var fieldValue = fieldInfo.GetValue(source) as INotifyChange;
            if (fieldValue == null)
            {
                MvxBindingTrace.Warning("INotifyChange is null for {0}", propertyNameToken.PropertyName);
                result = null;
                return false;
            }

            if (remainingTokens.Any())
            {
                result = new MvxChainedNotifyChangeFieldSourceBinding(source, fieldValue, remainingTokens);
            }
            else
            {
                result = new MvxLeafNotifyChangeFieldSourceBinding(source, fieldValue);
            }
            return true;
        }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken, List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return false;
            }

            if (remainingTokens.Count > 0)
            {
                result = null;
                return false;
            }

            var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;
            if (propertyNameToken == null)
            {
                result = null;
                return false;
            }

            var methodInfo = FindMethodInfo(source, propertyNameToken.PropertyName);

            if (methodInfo == null)
            {
                result = null;
                return false;
            }

            var parameters = methodInfo.GetParameters();
            if (parameters.Count(p => !p.IsOptional) > 1)
            {
                MvxBindingTrace.Warning("Problem binding to Method {0} - too many non-optional parameters");
            }

            result = new MvxMethodSourceBinding(source, methodInfo);
            return true;
        }
        protected bool TryCreateNotifyChangeBinding(object source, List <MvxPropertyToken> remainingTokens,
                                                    out IMvxSourceBinding result,
                                                    FieldInfo fieldInfo, MvxPropertyNamePropertyToken propertyNameToken)
        {
            var fieldValue = fieldInfo.GetValue(source) as INotifyChange;

            if (fieldValue == null)
            {
                MvxBindingTrace.Warning("INotifyChange is null for {0}", propertyNameToken.PropertyName);
                result = null;
                return(false);
            }

            if (remainingTokens.Any())
            {
                result = new MvxChainedNotifyChangeFieldSourceBinding(source, fieldValue, remainingTokens);
            }
            else
            {
                result = new MvxLeafNotifyChangeFieldSourceBinding(source, fieldValue);
            }
            return(true);
        }
 public MvxSourcePropertyBindingEventArgs(IMvxSourceBinding propertySourceBinding)
 {
     _value = propertySourceBinding.GetValue();
 }
示例#37
0
        protected bool TryCreateBindingFromExtensions(object source, MvxPropertyToken propertyToken,
                                                      List <MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            foreach (var extension in _extensions)
            {
                if (extension.TryCreateBinding(source, propertyToken, remainingTokens, out result))
                {
                    return(true);
                }
            }

            result = null;
            return(false);
        }
示例#38
0
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken, List <MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return(false);
            }

            if (remainingTokens.Count > 0)
            {
                result = null;
                return(false);
            }

            var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;

            if (propertyNameToken == null)
            {
                result = null;
                return(false);
            }

            var methodInfo = FindMethodInfo(source, propertyNameToken.PropertyName);

            if (methodInfo == null)
            {
                result = null;
                return(false);
            }

            var parameters = methodInfo.GetParameters();

            if (parameters.Count(p => !p.IsOptional) > 1)
            {
                MvxBindingLog.Warning("Problem binding to Method {0} - too many non-optional parameters");
            }

            result = new MvxMethodSourceBinding(source, methodInfo);
            return(true);
        }
 public MvxSourcePropertyBindingEventArgs(IMvxSourceBinding propertySourceBinding)
 {
     _value = propertySourceBinding.GetValue();
 }
 public MvxSourcePropertyBindingEventArgs(IMvxSourceBinding propertySourceBinding)
 {
     _isAvailable = propertySourceBinding.TryGetValue(out _value);
 }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken,
                                     List<MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source != null)
            {
                Type bindingSourceType = null;
                Type bindingTypeParameter = null;

                if (currentToken is MvxEmptyPropertyToken)
                {
                    var observable = source as IObservable<object>;
                    if (observable != null)
                    {
                        result = new ObservableMvxSourceBinding<object>(observable, typeof(object), this._mainThreadDispatcher, remainingTokens);
                        return true;
                    }

                    var implementedInterface = source
                        .GetType()
                        .GetTypeInfo()
                        .ImplementedInterfaces
                        .FirstOrDefault(iface => ((iface.IsConstructedGenericType) && (iface.GetGenericTypeDefinition() == typeof(IObservable<>))));
                       
                    if (implementedInterface != null)
                        bindingSourceType = bindingTypeParameter = implementedInterface.GenericTypeArguments[0];
                }
                else
                {
                    var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;
                    if (propertyNameToken != null)
                    {
                        var propertyInfo = this.FindPropertyInfo(source, propertyNameToken.PropertyName);
                        if (propertyInfo != null)
                        {
                            var propertyTypeInfo = propertyInfo.PropertyType.GetTypeInfo();
                            if ((propertyTypeInfo.IsGenericType) && (propertyTypeInfo.GetGenericTypeDefinition() == typeof(IObservable<>)))
                            {
                                source = propertyInfo.GetValue(source, ObservableMvxPropertySourceBindingFactoryExtension.EmptyObjectArray);

                                if (source != null)
                                {
                                    bindingSourceType = propertyTypeInfo.GenericTypeArguments[0];
                                    bindingTypeParameter = (bindingSourceType.GetTypeInfo().IsValueType)
                                        ? bindingSourceType
                                        : typeof(object);
                                }
                            }
                        }
                    }
                }

                if (bindingTypeParameter != null)
                {
                    result = (IMvxSourceBinding)Activator.CreateInstance(
                        typeof(ObservableMvxSourceBinding<>).MakeGenericType(bindingTypeParameter),
                        source,
                        bindingSourceType,
                        this._mainThreadDispatcher,
                        remainingTokens);

                    return true;
                }
            }

            result = null;
            return false;
        }
示例#42
0
 public MvxSourcePropertyBindingEventArgs(IMvxSourceBinding propertySourceBinding)
 {
     _isAvailable = propertySourceBinding.TryGetValue(out _value);
 }
示例#43
0
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken, List <MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source == null)
            {
                result = null;
                return(false);
            }

            result = remainingTokens.Count == 0 ? CreateLeafBinding(source, currentToken) : CreateChainedBinding(source, currentToken, remainingTokens);
            return(result != null);
        }
        public bool TryCreateBinding(object source, MvxPropertyToken currentToken,
                                     List <MvxPropertyToken> remainingTokens, out IMvxSourceBinding result)
        {
            if (source != null)
            {
                Type bindingSourceType    = null;
                Type bindingTypeParameter = null;

                if (currentToken is MvxEmptyPropertyToken)
                {
                    var observable = source as IObservable <object>;
                    if (observable != null)
                    {
                        result = new ObservableMvxSourceBinding <object>(observable, typeof(object), this._mainThreadDispatcher, remainingTokens);
                        return(true);
                    }

                    var implementedInterface = source
                                               .GetType()
                                               .GetTypeInfo()
                                               .ImplementedInterfaces
                                               .FirstOrDefault(iface => ((iface.IsConstructedGenericType) && (iface.GetGenericTypeDefinition() == typeof(IObservable <>))));

                    if (implementedInterface != null)
                    {
                        bindingSourceType = bindingTypeParameter = implementedInterface.GenericTypeArguments[0];
                    }
                }
                else
                {
                    var propertyNameToken = currentToken as MvxPropertyNamePropertyToken;
                    if (propertyNameToken != null)
                    {
                        var propertyInfo = this.FindPropertyInfo(source, propertyNameToken.PropertyName);
                        if (propertyInfo != null)
                        {
                            var propertyTypeInfo = propertyInfo.PropertyType.GetTypeInfo();
                            if ((propertyTypeInfo.IsGenericType) && (propertyTypeInfo.GetGenericTypeDefinition() == typeof(IObservable <>)))
                            {
                                source = propertyInfo.GetValue(source, ObservableMvxPropertySourceBindingFactoryExtension.EmptyObjectArray);

                                if (source != null)
                                {
                                    bindingSourceType    = propertyTypeInfo.GenericTypeArguments[0];
                                    bindingTypeParameter = (bindingSourceType.GetTypeInfo().IsValueType)
                                        ? bindingSourceType
                                        : typeof(object);
                                }
                            }
                        }
                    }
                }

                if (bindingTypeParameter != null)
                {
                    result = (IMvxSourceBinding)Activator.CreateInstance(
                        typeof(ObservableMvxSourceBinding <>).MakeGenericType(bindingTypeParameter),
                        source,
                        bindingSourceType,
                        this._mainThreadDispatcher,
                        remainingTokens);

                    return(true);
                }
            }

            result = null;
            return(false);
        }