/// <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; } }
/// <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)); }
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); }
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(); }
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; } }
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(); }
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); } } } }
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); }
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); }
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); }
/// <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; }