/// <summary>
 ///     Updates the current values.
 /// </summary>
 protected override void UpdateInternal()
 {
     try
     {
         if (_weakEventListener != null)
         {
             _weakEventListener.Dispose();
         }
         object source = GetActualSource();
         if (source == null || source.IsUnsetValue())
         {
             _pathMembers = UnsetBindingPathMembers.Instance;
         }
         else
         {
             IBindingMemberInfo lastMember = BindingServiceProvider
                                             .MemberProvider
                                             .GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, true);
             _pathMembers       = new SingleBindingPathMembers(OriginalSource as WeakReference ?? ToolkitExtensions.GetWeakReference(source), Path, lastMember);
             _weakEventListener = TryObserveMember(source, lastMember, this, Path.Path);
         }
     }
     catch (Exception)
     {
         _pathMembers = UnsetBindingPathMembers.Instance;
         throw;
     }
 }
Beispiel #2
0
        /// <summary>
        ///     Gets the raw value from source.
        /// </summary>
        protected override object GetRawValueInternal(IBindingMemberInfo targetMember, IDataContext context,
                                                      bool throwOnError)
        {
            IBindingPathMembers members = _bindingSource.GetPathMembers(throwOnError);

            return(members.LastMember.GetValue(members.PenultimateValue, null));
        }
Beispiel #3
0
 public void SetValue(BindingActionValue currentValue, object newValue, IBindingPathMembers pathMembers)
 {
     _path = pathMembers.Path;
     //it's normal here.
     lock (this)
     {
         if (_currentValue != null && Equals(currentValue.Member, _currentValue.Member) &&
             Equals(_currentValue.MemberSource.Target, currentValue.MemberSource.Target))
         {
             SetValue(newValue, pathMembers);
         }
         else
         {
             UnsubscribeEventHandler();
             currentValue.TrySetValue(new object[] { this }, out _subscriber);
             if (_subscriber != null)
             {
                 if (_path.IsDebuggable)
                 {
                     DebugInfo($"Binding subscribed to event: '{pathMembers.LastMember.Path}'", new object[] { pathMembers });
                 }
                 _currentValue = currentValue;
                 SetValue(newValue, pathMembers);
             }
         }
     }
 }
        protected override object GetRawValueInternal(IBindingMemberInfo targetMember, IDataContext context, bool throwOnError)
        {
            var values = new object[_sources.Length];

            for (int i = 0; i < _sources.Length; i++)
            {
                IBindingPathMembers members = _sources[i].GetPathMembers(true);
                object value = members.GetLastMemberValue();
                if (members.Path.IsDebuggable)
                {
                    DebugInfo($"MultiBinding got a raw value: '{value}', for path: '{members.Path}'", new[] { value, members });
                }
                if (value.IsDoNothing())
                {
                    return(BindingConstants.DoNothing);
                }
                if (value.IsUnsetValue())
                {
                    return(BindingConstants.UnsetValue);
                }
                values[i] = value;
            }
            if (_sources[0].Path.IsDebuggable)
            {
                DebugInfo("MultiBinding applying format expression", new object[] { _formatExpression, values });
                var result = _formatExpression(context, values);
                DebugInfo($"MultiBinding format expression returns value: '{result}'");
                return(result);
            }
            return(_formatExpression(context, values));
        }
 public void Dispose()
 {
     if (Interlocked.Exchange(ref _state, DisposedState) == DisposedState)
     {
         return;
     }
     _pathMembers  = UnsetBindingPathMembers.Instance;
     _valueChanged = null;
     if (_sourceListener != null)
     {
         _sourceListener.Dispose();
         _sourceListener = null;
     }
     _observationException = DisposedException;
     if (_source is WeakReference)
     {
         _source = Empty.WeakReference;
     }
     else
     {
         (_source as IDisposable)?.Dispose();
         _source = EmptySource;
     }
     OnDispose();
     if (Path.IsDebuggable)
     {
         DebugInfo("Observer disposed");
     }
 }
 /// <summary>
 ///     Initializes a new instance of the <see cref="SinglePathObserver" /> class.
 /// </summary>
 public SinglePathObserver([NotNull] object source, [NotNull] IBindingPath path, bool ignoreAttachedMembers)
     : base(source, path)
 {
     Should.BeSupported(path.IsSingle, "The SinglePathObserver supports only single path members.");
     _ignoreAttachedMembers = ignoreAttachedMembers;
     _pathMembers           = UnsetBindingPathMembers.Instance;
     Update();
 }
        protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
        {
            object source = GetActualSource();

            if (source == null || source.IsUnsetValue())
            {
                return(UnsetBindingPathMembers.Instance);
            }
            bool allMembersAvailable = true;
            IBindingMemberProvider memberProvider = BindingServiceProvider.MemberProvider;
            IList <string>         items          = Path.Parts;

            //Trying to get member using full path with dot, example BindingErrorProvider.Errors or ErrorProvider.Errors.
            if (items.Count == 2)
            {
                var pathMember = memberProvider.GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, false);
                if (pathMember != null)
                {
                    var observer = TryObserveMember(source, pathMember, true);
                    if (observer != null)
                    {
                        _listeners.Add(observer);
                    }
                    return(new MultiBindingPathMembers(_lastMemberListener.Reference, source, new[] { pathMember }));
                }
            }


            int lastIndex = items.Count - 1;
            var members   = new List <IBindingMemberInfo>();

            for (int index = 0; index < items.Count; index++)
            {
                string             name       = items[index];
                IBindingMemberInfo pathMember = memberProvider
                                                .GetBindingMember(source.GetType(), name, _ignoreAttachedMembers, true);
                members.Add(pathMember);
                var observer = TryObserveMember(source, pathMember, index == lastIndex);
                if (observer != null)
                {
                    _listeners.Add(observer);
                }
                if (index == lastIndex)
                {
                    break;
                }
                source = pathMember.GetValue(source, null);
                if (source == null || source.IsUnsetValue())
                {
                    allMembersAvailable = false;
                    break;
                }
            }

            return(allMembersAvailable
                ? new MultiBindingPathMembers(_lastMemberListener.Reference, source, members)
                : UnsetBindingPathMembers.Instance);
        }
Beispiel #8
0
        public static object GetLastMemberValue(this IBindingPathMembers members, object[] args = null)
        {
            var penultimateValue = members.PenultimateValue;

            if (penultimateValue.IsUnsetValue() || (penultimateValue == null && !members.AllMembersAvailable))
            {
                return(BindingConstants.UnsetValue);
            }
            return(members.LastMember.GetValue(penultimateValue, args));
        }
        private static void SetErrors(IBindingErrorProvider errorProvider, IDataBinding sender, object[] errors)
        {
            IBindingPathMembers pathMembers = sender.TargetAccessor.Source.GetPathMembers(false);
            object target = pathMembers.PenultimateValue;

            if (target != null && !target.IsUnsetValue())
            {
                errorProvider.SetErrors(target, Key + pathMembers.Path.Path, errors, sender.Context);
            }
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="MultiPathObserver" /> class.
 /// </summary>
 public MultiPathObserver([NotNull] object source, [NotNull] IBindingPath path, bool ignoreAttachedMembers)
     : base(source, path)
 {
     Should.BeSupported(!path.IsEmpty, "The MultiPathObserver doesn't support the empty path members.");
     _listeners             = new List <IDisposable>(path.Parts.Count - 1);
     _ignoreAttachedMembers = ignoreAttachedMembers;
     _members            = UnsetBindingPathMembers.Instance;
     _selfReference      = ServiceProvider.WeakReferenceFactory(this, true);
     _lastMemberListener = new LastMemberListener(_selfReference);
     Update();
 }
Beispiel #11
0
        private void Update(bool notify)
        {
            if (Interlocked.CompareExchange(ref _state, UpdatingState, DefaultState) != DefaultState)
            {
                return;
            }
            Exception ex             = null;
            var       hasSubscribers = _valueChanged != null;

            try
            {
                if (_sourceListener == null)
                {
                    InitializeSourceListener();
                }
                _pathMembers = UpdateInternal(_pathMembers, hasSubscribers);
                if (Path.IsDebuggable)
                {
                    if (_pathMembers.AllMembersAvailable)
                    {
                        DebugInfo($"Value is available, source: '{GetActualSource()}'", new[] { Source });
                    }
                    else
                    {
                        DebugInfo($"Value is not available, source: '{Source}', actual source '{GetActualSource()}'", new[] { Source });
                    }
                }
            }
            catch (Exception exception)
            {
                ex           = exception;
                _pathMembers = UnsetBindingPathMembers.Instance;
                if (Path.IsDebuggable)
                {
                    DebugInfo($"Error update: {exception.Flatten(true)}", new object[] { exception });
                }
            }
            finally
            {
                if (Interlocked.CompareExchange(ref _state, DefaultState, UpdatingState) == UpdatingState)
                {
                    _observationException = ex;
                    if (!hasSubscribers && _valueChanged != null)
                    {
                        Update(true);
                    }
                    else if (notify)
                    {
                        RaiseValueChanged(ValueChangedEventArgs.FalseEventArgs);
                    }
                }
            }
        }
        protected override object GetRawValueInternal(IBindingMemberInfo targetMember, IDataContext context,
                                                      bool throwOnError)
        {
            IBindingPathMembers members = _bindingSource.GetPathMembers(throwOnError);
            var value = members.GetLastMemberValue();

            if (members.Path.IsDebuggable)
            {
                DebugInfo($"Binding got a raw value: '{value}', for path: '{members.Path}'", new[] { value, members });
            }
            return(value);
        }
        /// <summary>
        ///     Updates the current values.
        /// </summary>
        protected override void UpdateInternal()
        {
            try
            {
                ClearListeners();
                object source = GetActualSource();
                if (source == null || source.IsUnsetValue())
                {
                    _members = UnsetBindingPathMembers.Instance;
                    return;
                }
                bool allMembersAvailable = true;
                IBindingMemberProvider memberProvider = BindingServiceProvider.MemberProvider;
                IList <string>         items          = Path.Parts;
                int lastIndex = items.Count - 1;
                var members   = new List <IBindingMemberInfo>();
                for (int index = 0; index < items.Count; index++)
                {
                    string             name       = items[index];
                    IBindingMemberInfo pathMember = memberProvider
                                                    .GetBindingMember(source.GetType(), name, _ignoreAttachedMembers, true);
                    members.Add(pathMember);
                    var observer = TryObserveMember(source, pathMember, index == lastIndex);
                    if (observer != null)
                    {
                        _listeners.Add(observer);
                    }
                    if (index == lastIndex)
                    {
                        break;
                    }
                    source = pathMember.GetValue(source, null);
                    if (source == null || source.IsUnsetValue())
                    {
                        allMembersAvailable = false;
                        break;
                    }
                }

                _members = allMembersAvailable
                    ? new MultiBindingPathMembers(_selfReference, source, Path, members)
                    : UnsetBindingPathMembers.Instance;
            }
            catch (Exception)
            {
                _members = UnsetBindingPathMembers.Instance;
                throw;
            }
        }
Beispiel #14
0
        public void SourceShouldReturnMembersFromObserver()
        {
            var mock = new ObserverMock {
                PathMembers = UnsetBindingPathMembers.Instance
            };
            BindingSource       target      = CreateBindingSource(mock);
            IBindingPathMembers pathMembers = target.GetPathMembers(true);

            pathMembers.ShouldEqual(UnsetBindingPathMembers.Instance);
            pathMembers.AllMembersAvailable.ShouldBeFalse();

            mock.PathMembers = new BindingPathMembersMock(this, BindingPath.Empty,
                                                          new BindingMemberInfo(PropertyInfo.Name, PropertyInfo, PropertyInfo.DeclaringType));
            pathMembers = target.GetPathMembers(true);
            pathMembers.ShouldEqual(mock.PathMembers);
            pathMembers.AllMembersAvailable.ShouldBeTrue();
        }
Beispiel #15
0
        internal static object GetCurrentValue(this IObserver source)
        {
            IBindingPathMembers pathMembers = source.GetPathMembers(true);
            object value = pathMembers.LastMember.GetValue(pathMembers.PenultimateValue, null);

            if (value.IsUnsetValue())
            {
                return(null);
            }
            var actionValue = value as BindingActionValue;

            if (actionValue == null)
            {
                return(value);
            }
            return(actionValue.GetValue(null));
        }
        protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
        {
            object source = GetActualSource();

            if (source.IsNullOrUnsetValue())
            {
                return(UnsetBindingPathMembers.Instance);
            }
            var members = oldPath as SingleBindingPathMembers;
            var srcRef  = OriginalSource as WeakReference;

            if (members != null)
            {
                if (srcRef != null || ReferenceEquals(members.Source, source))
                {
                    if (hasSubscribers && _observable && _weakEventListener == null)
                    {
                        _weakEventListener = TryObserveMember(source, members.LastMember, this, Path.Path);
                    }
                    return(members);
                }
                if (_hasStablePath)
                {
                    members.Reference = ToolkitExtensions.GetWeakReference(source);
                    if (hasSubscribers && _observable)
                    {
                        _weakEventListener?.Dispose();
                        _weakEventListener = TryObserveMember(source, members.LastMember, this, Path.Path);
                    }
                    return(members);
                }
            }
            IBindingMemberInfo lastMember = GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, _optional);

            if (lastMember == null)
            {
                return(UnsetBindingPathMembers.Instance);
            }

            if (_observable && hasSubscribers)
            {
                _weakEventListener?.Dispose();
                _weakEventListener = TryObserveMember(source, lastMember, this, Path.Path);
            }
            return(new SingleBindingPathMembers(srcRef ?? ToolkitExtensions.GetWeakReference(source), Path, lastMember));
        }
            private void SetValue(object newValue, IBindingPathMembers pathMembers)
            {
                if (newValue == null)
                {
                    UnsubscribeCommand();
                    _valueReference = null;
                    return;
                }

                var command = newValue as ICommand;

                if (command == null)
                {
                    if (!(newValue is BindingActionValue))
                    {
                        throw BindingExceptionManager.InvalidEventSourceValue(_currentValue.Member, newValue);
                    }
                    _valueReference = newValue;
                    if (_path.IsDebuggable)
                    {
                        DebugInfo($"Binding will use event: '{pathMembers.LastMember.Path}' to update member: '{((BindingActionValue)newValue).Member.Path}'", new[] { newValue });
                    }
                }
                else
                {
                    var reference = _valueReference as WeakReference;
                    if (reference != null && ReferenceEquals(reference.Target, command))
                    {
                        return;
                    }
                    if (_path.IsDebuggable)
                    {
                        DebugInfo($"Binding will use event: '{pathMembers.LastMember.Path}' to update command: '{newValue}'", new[] { newValue });
                    }
                    UnsubscribeCommand();
                    _valueReference = ToolkitExtensions.GetWeakReferenceOrDefault(command, null, true);
                    if (_toggleEnabledState && InitializeCanExecuteDelegate(command))
                    {
                        CommandOnCanExecuteChanged(command);
                        command.CanExecuteChanged += _canExecuteHandler;
                    }
                }
            }
        private void Update(bool notify)
        {
            if (Interlocked.CompareExchange(ref _state, UpdatingState, DefaultState) != DefaultState)
            {
                return;
            }
            Exception ex             = null;
            var       hasSubscribers = _valueChanged != null;

            try
            {
                if (_sourceListener == null)
                {
                    if (hasSubscribers || !DependsOnSubscribers)
                    {
                        InitializeSourceListener();
                    }
                }
                ClearObserversInternal();
                _pathMembers = UpdateInternal(_pathMembers, hasSubscribers);
            }
            catch (Exception exception)
            {
                ex           = exception;
                _pathMembers = UnsetBindingPathMembers.Instance;
            }
            finally
            {
                if (Interlocked.CompareExchange(ref _state, DefaultState, UpdatingState) == UpdatingState)
                {
                    _observationException = ex;
                    if (DependsOnSubscribers && !hasSubscribers && _valueChanged != null)
                    {
                        Update(true);
                    }
                    else if (notify)
                    {
                        RaiseValueChanged(ValueChangedEventArgs.FalseEventArgs);
                    }
                }
            }
        }
Beispiel #19
0
        protected override object GetRawValueInternal(IBindingMemberInfo targetMember, IDataContext context,
                                                      bool throwOnError)
        {
            var values = new object[_sources.Length];

            for (int i = 0; i < _sources.Length; i++)
            {
                IBindingPathMembers members = _sources[i].GetPathMembers(true);
                object value = members.LastMember.GetValue(members.PenultimateValue, null);
                if (value.IsDoNothing())
                {
                    return(BindingConstants.DoNothing);
                }
                if (value.IsUnsetValue())
                {
                    return(BindingConstants.UnsetValue);
                }
                values[i] = value;
            }
            return(_formatExpression(context, values));
        }
 static UnsetBindingPathMembers()
 {
     Instance = new UnsetBindingPathMembers();
 }
 /// <summary>
 ///     Initializes a new instance of the <see cref="MultiPathObserver" /> class.
 /// </summary>
 public MultiPathObserver([NotNull] object source, [NotNull] IBindingPath path, bool ignoreAttachedMembers)
     : base(source, path)
 {
     Should.BeSupported(!path.IsEmpty, "The MultiPathObserver doesn't support the empty path members.");
     _listeners = new List<IDisposable>(path.Parts.Count - 1);
     _ignoreAttachedMembers = ignoreAttachedMembers;
     _members = UnsetBindingPathMembers.Instance;
     _lastMemberListener = new LastMemberListener(ServiceProvider.WeakReferenceFactory(this));
     Initialize(this);
 }
Beispiel #22
0
 protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
 {
     return(_members);
 }
        protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
        {
            object source = GetActualSource();
            if (source == null || source.IsUnsetValue())
                return UnsetBindingPathMembers.Instance;
            var members = oldPath as SingleBindingPathMembers;
            var srcRef = OriginalSource as WeakReference;
            if (members != null)
            {
                if (srcRef != null || ReferenceEquals(members.Source, source))
                {
                    if (hasSubscribers && _observable && _weakEventListener == null)
                        _weakEventListener = TryObserveMember(source, members.LastMember, this, Path.Path);
                    return members;
                }
                if (_hasStablePath)
                {
                    members.Reference = ToolkitExtensions.GetWeakReference(source);
                    if (hasSubscribers && _observable)
                    {
                        _weakEventListener?.Dispose();
                        _weakEventListener = TryObserveMember(source, members.LastMember, this, Path.Path);
                    }
                    return members;
                }
            }
            IBindingMemberInfo lastMember = GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, _optional);
            if (lastMember == null)
                return UnsetBindingPathMembers.Instance;

            if (_observable && hasSubscribers)
            {
                _weakEventListener?.Dispose();
                _weakEventListener = TryObserveMember(source, lastMember, this, Path.Path);
            }
            return new SingleBindingPathMembers(srcRef ?? ToolkitExtensions.GetWeakReference(source), Path, lastMember);
        }
        protected override bool SetValueInternal(IBindingSourceAccessor targetAccessor, IDataContext context,
                                                 bool throwOnError)
        {
            IBindingPathMembers members = _bindingSource.GetPathMembers(throwOnError);

            if (!members.AllMembersAvailable)
            {
                return(false);
            }

            object             penultimateValue = members.PenultimateValue;
            IBindingMemberInfo lastMember       = members.LastMember;

            object oldValue;
            object newValue = targetAccessor.GetValue(lastMember, context, throwOnError);

            if (lastMember.CanRead && !BindingMemberType.BindingContext.EqualsWithoutNullCheck(lastMember.MemberType))
            {
                oldValue = lastMember.GetValue(penultimateValue, null);
                if (ReferenceEquals(oldValue, newValue) || newValue.IsUnsetValueOrDoNothing())
                {
                    return(false);
                }
            }
            else
            {
                oldValue = BindingConstants.UnsetValue;
                if (newValue.IsUnsetValueOrDoNothing())
                {
                    return(false);
                }
            }

            ValueAccessorChangingEventArgs args = null;

            if (ValueChanging != null)
            {
                args = RaiseValueChanging(context, penultimateValue, lastMember, oldValue, newValue);
                if (args != null)
                {
                    if (args.Cancel)
                    {
                        return(false);
                    }
                    if (!ReferenceEquals(newValue, args.NewValue))
                    {
                        newValue = args.NewValue;
                        if (newValue.IsUnsetValueOrDoNothing())
                        {
                            return(false);
                        }
                    }
                }
            }
            newValue = BindingServiceProvider.ValueConverter(lastMember, lastMember.Type, newValue);
            if (Equals(oldValue, newValue))
            {
                return(false);
            }
            if (BindingMemberType.Event.EqualsWithoutNullCheck(lastMember.MemberType))
            {
                TryRegisterEvent((BindingActionValue)oldValue, newValue, context);
                RaiseValueChanged(context, penultimateValue, lastMember, oldValue, newValue, args);
            }
            else
            {
                if (_closure != null)
                {
                    _closure.Unsubscribe(false, _isOneTime);
                }
                lastMember.SetSingleValue(penultimateValue, newValue);
                if (ValueChanged != null)
                {
                    RaiseValueChanged(context, penultimateValue, lastMember, oldValue, newValue, args);
                }
            }
            return(true);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="SinglePathObserver" /> class.
 /// </summary>
 public SinglePathObserver([NotNull] object source, [NotNull] IBindingPath path, bool ignoreAttachedMembers)
     : base(source, path)
 {
     Should.BeSupported(path.IsSingle, "The SinglePathObserver supports only single path members.");
     _ignoreAttachedMembers = ignoreAttachedMembers;
     _pathMembers = UnsetBindingPathMembers.Instance;
     _ref = ServiceProvider.WeakReferenceFactory(this);
     Initialize(null);
 }
 /// <summary>
 ///     Releases resources held by the object.
 /// </summary>
 protected override void OnDispose()
 {
     ClearListeners();
     _members = UnsetBindingPathMembers.Instance;
     base.OnDispose();
 }
 protected abstract IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers);
        protected override bool SetValueInternal(IBindingSourceAccessor targetAccessor, IDataContext context,
                                                 bool throwOnError)
        {
            IBindingPathMembers members = _bindingSource.GetPathMembers(throwOnError);
            object penultimateValue     = members.PenultimateValue;

            if (penultimateValue.IsUnsetValue() || (penultimateValue == null && !members.AllMembersAvailable))
            {
                if (members.Path.IsDebuggable)
                {
                    DebugInfo($"Binding cannot set value for path {members.Path.Path}", new object[] { members });
                }
                return(false);
            }

            IBindingMemberInfo lastMember = members.LastMember;
            object             oldValue;
            object             newValue = targetAccessor.GetValue(lastMember, context, throwOnError);

            if (lastMember.CanRead && !BindingMemberType.BindingContext.EqualsWithoutNullCheck(lastMember.MemberType))
            {
                if (_disableEqualityChecking && !BindingMemberType.Event.EqualsWithoutNullCheck(lastMember.MemberType))
                {
                    oldValue = BindingConstants.UnsetValue;
                }
                else
                {
                    oldValue = lastMember.GetValue(penultimateValue, null);
                }
                if (ReferenceEquals(oldValue, newValue) || newValue.IsUnsetValueOrDoNothing())
                {
                    if (members.Path.IsDebuggable)
                    {
                        DebugInfo($"Binding ignores setter because old value: '{oldValue}' equals to new value '{newValue}'", new[] { members, oldValue, newValue });
                    }
                    return(false);
                }
            }
            else
            {
                oldValue = BindingConstants.UnsetValue;
                if (newValue.IsUnsetValueOrDoNothing())
                {
                    if (members.Path.IsDebuggable)
                    {
                        DebugInfo($"Binding ignores setter for value '{newValue}'", new[] { members, newValue });
                    }
                    return(false);
                }
            }

            ValueAccessorChangingEventArgs args = null;

            if (ValueChanging != null)
            {
                args = RaiseValueChanging(context, penultimateValue, lastMember, oldValue, newValue);
                if (args != null)
                {
                    if (args.Cancel)
                    {
                        return(false);
                    }
                    if (!ReferenceEquals(newValue, args.NewValue))
                    {
                        newValue = args.NewValue;
                        if (newValue.IsUnsetValueOrDoNothing())
                        {
                            if (members.Path.IsDebuggable)
                            {
                                DebugInfo($"Binding ignores setter for value '{newValue}'", new[] { members, newValue });
                            }
                            return(false);
                        }
                    }
                }
            }
            newValue = BindingServiceProvider.ValueConverter(lastMember, lastMember.Type, newValue);
            if (Equals(oldValue, newValue))
            {
                if (members.Path.IsDebuggable)
                {
                    DebugInfo($"Binding ignores setter because old value: '{oldValue}' equals to new value '{newValue}'", new[] { members, oldValue, newValue });
                }
                return(false);
            }
            if (BindingMemberType.Event.EqualsWithoutNullCheck(lastMember.MemberType))
            {
                TryRegisterEvent((BindingActionValue)oldValue, newValue, context, members);
                RaiseValueChanged(context, penultimateValue, lastMember, oldValue, newValue, args);
            }
            else
            {
                _closure?.Unsubscribe(false, _isOneTime);
                lastMember.SetSingleValue(penultimateValue, newValue);
                if (members.Path.IsDebuggable)
                {
                    DebugInfo($"Binding set value: '{newValue}' for source: '{penultimateValue}' with path: '{lastMember.Path}'", new[] { newValue, penultimateValue, lastMember });
                }
                if (ValueChanged != null)
                {
                    RaiseValueChanged(context, penultimateValue, lastMember, oldValue, newValue, args);
                }
            }
            return(true);
        }
 static UnsetBindingPathMembers()
 {
     Instance = new UnsetBindingPathMembers();
 }
Beispiel #30
0
        protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
        {
            object source = GetActualSource();

            if (source.IsNullOrUnsetValue())
            {
                return(UnsetBindingPathMembers.Instance);
            }
            ClearListeners();
            int lastIndex;

            if (_hasStablePath)
            {
                var pathMembers = oldPath as MultiBindingPathMembers;
                if (pathMembers != null)
                {
                    var list = pathMembers.Members;
                    lastIndex = list.Count - 1;
                    for (int index = 0; index < list.Count; index++)
                    {
                        var pathMember = list[index];
                        if (_observable)
                        {
                            var observer = TryObserveMember(source, pathMember, index == lastIndex);
                            if (observer != null)
                            {
                                _listeners.Add(observer);
                            }
                        }
                        if (index == lastIndex)
                        {
                            break;
                        }
                        source = pathMember.GetValue(source, null);
                        if (source.IsNullOrUnsetValue())
                        {
                            if (Path.IsDebuggable)
                            {
                                DebugInfo($"Value is not available for '{pathMember.Path}'", new[] { GetActualSource(false) });
                            }
                            return(UnsetBindingPathMembers.Instance);
                        }
                    }
                    pathMembers.PenultimateValueRef = ToolkitExtensions.GetWeakReference(source);
                    return(pathMembers);
                }
            }

            IList <string> items = Path.Parts;

            lastIndex = items.Count - 1;
            var members = new List <IBindingMemberInfo>();

            for (int index = 0; index < items.Count; index++)
            {
                IBindingMemberInfo pathMember = GetBindingMember(source.GetType(), items[index], _ignoreAttachedMembers, _optional);
                if (pathMember == null)
                {
                    return(UnsetBindingPathMembers.Instance);
                }
                members.Add(pathMember);
                if (_observable)
                {
                    var observer = TryObserveMember(source, pathMember, index == lastIndex);
                    if (observer != null)
                    {
                        _listeners.Add(observer);
                    }
                }
                if (index == lastIndex)
                {
                    break;
                }
                source = pathMember.GetValue(source, null);
                if (source.IsNullOrUnsetValue())
                {
                    if (Path.IsDebuggable)
                    {
                        DebugInfo($"Value is not available for '{pathMember.Path}'", new[] { GetActualSource(false) });
                    }
                    return(UnsetBindingPathMembers.Instance);
                }
            }

            return(new MultiBindingPathMembers(_lastMemberListener.Reference, source, members));
        }
 protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
 {
     object source = GetActualSource();
     if (source == null || source.IsUnsetValue())
         return UnsetBindingPathMembers.Instance;
     var srcRef = OriginalSource as WeakReference;
     if (oldPath != null && srcRef != null)
     {
         var members = oldPath as SingleBindingPathMembers;
         if (members != null)
         {
             if (hasSubscribers)
                 _weakEventListener = TryObserveMember(source, members.LastMember, this, Path.Path);
             return members;
         }
     }
     IBindingMemberInfo lastMember = BindingServiceProvider
         .MemberProvider
         .GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, true);
     if (hasSubscribers || srcRef == null)
         _weakEventListener = TryObserveMember(source, lastMember, this, Path.Path);
     return new SingleBindingPathMembers(srcRef ?? ToolkitExtensions.GetWeakReference(source), Path, lastMember);
 }
Beispiel #32
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="EmptyPathObserver" /> class.
 /// </summary>
 public EmptyPathObserver([NotNull] object source, [NotNull] IBindingPath path)
     : base(source, path)
 {
     Should.BeSupported(path.IsEmpty, "The EmptyPathObserver supports only empty path members.");
     _members = new EmptyBindingPathMembers(this);
 }
 /// <summary>
 ///     Updates the current values.
 /// </summary>
 protected override void UpdateInternal()
 {
     try
     {
         ClearListener();
         object source = GetActualSource();
         if (source == null || source.IsUnsetValue())
             _pathMembers = UnsetBindingPathMembers.Instance;
         else
         {
             IBindingMemberInfo lastMember = BindingServiceProvider
                 .MemberProvider
                 .GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, true);
             _pathMembers = new SingleBindingPathMembers(OriginalSource as WeakReference ?? ToolkitExtensions.GetWeakReference(source), Path, lastMember);
             _weakEventListener = TryObserveMember(source, lastMember, this, Path.Path);
         }
     }
     catch
     {
         _pathMembers = UnsetBindingPathMembers.Instance;
         throw;
     }
 }
        protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
        {
            object source = GetActualSource();
            if (source == null || source.IsUnsetValue())
                return UnsetBindingPathMembers.Instance;
            ClearListeners();
            int lastIndex;
            if (_hasStablePath)
            {
                var pathMembers = oldPath as MultiBindingPathMembers;
                if (pathMembers != null)
                {
                    var list = pathMembers.Members;
                    lastIndex = list.Count - 1;
                    for (int index = 0; index < list.Count; index++)
                    {
                        var pathMember = list[index];
                        if (_observable)
                        {
                            var observer = TryObserveMember(source, pathMember, index == lastIndex);
                            if (observer != null)
                                _listeners.Add(observer);
                        }
                        if (index == lastIndex)
                            break;
                        source = pathMember.GetValue(source, null);
                        if (source == null || source.IsUnsetValue())
                            return UnsetBindingPathMembers.Instance;
                    }
                    pathMembers.PenultimateValueRef = ToolkitExtensions.GetWeakReference(source);
                    return pathMembers;
                }
            }

            IList<string> items = Path.Parts;
            lastIndex = items.Count - 1;
            var members = new List<IBindingMemberInfo>();
            for (int index = 0; index < items.Count; index++)
            {
                IBindingMemberInfo pathMember = GetBindingMember(source.GetType(), items[index], _ignoreAttachedMembers, _optional);
                if (pathMember == null)
                    return UnsetBindingPathMembers.Instance;
                members.Add(pathMember);
                if (_observable)
                {
                    var observer = TryObserveMember(source, pathMember, index == lastIndex);
                    if (observer != null)
                        _listeners.Add(observer);
                }
                if (index == lastIndex)
                    break;
                source = pathMember.GetValue(source, null);
                if (source == null || source.IsUnsetValue())
                    return UnsetBindingPathMembers.Instance;
            }

            return new MultiBindingPathMembers(_lastMemberListener.Reference, source, members);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="EmptyPathObserver" /> class.
 /// </summary>
 public EmptyPathObserver([NotNull] object source, [NotNull] IBindingPath path)
     : base(source, path)
 {
     Should.BeSupported(path.IsEmpty, "The EmptyPathObserver supports only empty path members.");
     _members = new EmptyBindingPathMembers(ServiceProvider.WeakReferenceFactory(this));
     Initialize((IEventListener)_members);
 }
        /// <summary>
        ///     Updates the current values.
        /// </summary>
        protected override void UpdateInternal()
        {
            try
            {
                ClearListeners();
                object source = GetActualSource();
                if (source == null || source.IsUnsetValue())
                {
                    _members = UnsetBindingPathMembers.Instance;
                    return;
                }
                bool allMembersAvailable = true;
                IBindingMemberProvider memberProvider = BindingServiceProvider.MemberProvider;
                IList<string> items = Path.Parts;

                //Trying to get member using full path with dot, example BindingErrorProvider.Errors or ErrorProvider.Errors.                
                if (items.Count == 2)
                {
                    var pathMember = memberProvider.GetBindingMember(source.GetType(), Path.Path, _ignoreAttachedMembers, false);
                    if (pathMember != null)
                    {
                        var observer = TryObserveMember(source, pathMember, true);
                        if (observer != null)
                            _listeners.Add(observer);
                        _members = new MultiBindingPathMembers(_lastMemberListener.Reference, source, Path, new[] { pathMember });
                        return;
                    }
                }


                int lastIndex = items.Count - 1;
                var members = new List<IBindingMemberInfo>();
                for (int index = 0; index < items.Count; index++)
                {
                    string name = items[index];
                    IBindingMemberInfo pathMember = memberProvider
                        .GetBindingMember(source.GetType(), name, _ignoreAttachedMembers, true);
                    members.Add(pathMember);
                    var observer = TryObserveMember(source, pathMember, index == lastIndex);
                    if (observer != null)
                        _listeners.Add(observer);
                    if (index == lastIndex)
                        break;
                    source = pathMember.GetValue(source, null);
                    if (source == null || source.IsUnsetValue())
                    {
                        allMembersAvailable = false;
                        break;
                    }
                }

                _members = allMembersAvailable
                    ? new MultiBindingPathMembers(_lastMemberListener.Reference, source, Path, members)
                    : UnsetBindingPathMembers.Instance;
            }
            catch (Exception)
            {
                _members = UnsetBindingPathMembers.Instance;
                throw;
            }
        }
 private void TryRegisterEvent(BindingActionValue bindingActionValue, object newValue, IDataContext context, IBindingPathMembers pathMembers)
 {
     if (newValue == null && _closure == null)
     {
         return;
     }
     if (_closure == null)
     {
         Interlocked.CompareExchange(ref _closure, new EventClosure(_bindingSource, _toggleEnabledState && IsTarget, Parameters?.CommandParameterDelegate), null);
     }
     _closure.LastContext = context;
     _closure.SetValue(bindingActionValue, newValue, pathMembers);
 }
 protected override IBindingPathMembers UpdateInternal(IBindingPathMembers oldPath, bool hasSubscribers)
 {
     return _members;
 }