void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess) { if (property == null) { throw new ArgumentNullException(nameof(property)); } if (checkAccess && property.IsReadOnly) { throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); } BindablePropertyContext bpcontext = GetContext(property); if (bpcontext == null) { return; } if (fromStyle && !CanBeSetFromStyle(property)) { return; } object original = bpcontext.Value; object newValue = property.GetDefaultValue(this); bool same = Equals(original, newValue); if (!same) { property.PropertyChanging?.Invoke(this, original, newValue); OnPropertyChanging(property.PropertyName); } bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet; bpcontext.Value = newValue; if (property.DefaultValueCreator == null) { bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue; } else { bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated; } if (!same) { OnPropertyChanged(property.PropertyName); property.PropertyChanged?.Invoke(this, original, newValue); } }
void ClearValue(BindableProperty property, bool checkaccess) { if (property == null) { throw new ArgumentNullException("property"); } if (checkaccess && property.IsReadOnly) { throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); } BindablePropertyContext bpcontext = GetContext(property); if (bpcontext == null) { return; } object original = bpcontext.Value; object newValue = property.GetDefaultValue(this); bool same = Equals(original, newValue); if (!same) { if (property.PropertyChanging != null) { property.PropertyChanging(this, original, newValue); } OnPropertyChanging(property.PropertyName); } bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet; bpcontext.Value = newValue; bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue; if (!same) { OnPropertyChanged(property.PropertyName); if (property.PropertyChanged != null) { property.PropertyChanged(this, original, newValue); } } }
/// <summary> /// Applies the binding expression to a previously set source or target. /// </summary> void ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget = false) { BindingMode mode = Binding.GetRealizedMode(_targetProperty); if ((mode == BindingMode.OneWay || mode == BindingMode.OneTime) && fromTarget) { return; } bool needsGetter = (mode == BindingMode.TwoWay && !fromTarget) || mode == BindingMode.OneWay || mode == BindingMode.OneTime; bool needsSetter = !needsGetter && ((mode == BindingMode.TwoWay && fromTarget) || mode == BindingMode.OneWayToSource); object current = sourceObject; BindingExpressionPart part = null; for (var i = 0; i < _parts.Count; i++) { part = _parts[i]; if (!part.IsSelf && current != null) { // Allow the object instance itself to provide its own TypeInfo TypeInfo currentType = current is IReflectableType reflectable?reflectable.GetTypeInfo() : current.GetType().GetTypeInfo(); if (part.LastGetter == null || !part.LastGetter.DeclaringType.GetTypeInfo().IsAssignableFrom(currentType)) { SetupPart(currentType, part); } if (i < _parts.Count - 1) { part.TryGetValue(current, out current); } } if (!part.IsSelf && current != null && ((needsGetter && part.LastGetter == null) || (needsSetter && part.NextPart == null && part.LastSetter == null))) { Log.Warning("Binding", PropertyNotFoundErrorMessage, part.Content, current, target.GetType(), property.PropertyName); break; } if (part.NextPart != null && (mode == BindingMode.OneWay || mode == BindingMode.TwoWay) && current is INotifyPropertyChanged inpc) { part.Subscribe(inpc); } } Debug.Assert(part != null, "There should always be at least the self part in the expression."); if (needsGetter) { if (part.TryGetValue(current, out object value) || part.IsSelf) { value = Binding.GetSourceValue(value, property.ReturnType); } else { value = Binding.FallbackValue ?? property.GetDefaultValue(target); } if (!TryConvert(ref value, property, property.ReturnType, true)) { Log.Warning("Binding", "{0} can not be converted to type '{1}'", value, property.ReturnType); return; } target.SetValueCore(property, value, SetValueFlags.ClearDynamicResource, BindableObject.SetValuePrivateFlags.Default | BindableObject.SetValuePrivateFlags.Converted); } else if (needsSetter && part.LastSetter != null && current != null) { object value = Binding.GetTargetValue(target.GetValue(property), part.SetterType); if (!TryConvert(ref value, property, part.SetterType, false)) { Log.Warning("Binding", "{0} can not be converted to type '{1}'", value, part.SetterType); return; } object[] args; if (part.IsIndexer) { args = new object[part.Arguments.Length + 1]; part.Arguments.CopyTo(args, 0); args[args.Length - 1] = value; } else if (part.IsBindablePropertySetter) { args = new[] { part.BindablePropertyField, value }; } else { args = new[] { value }; } part.LastSetter.Invoke(current, args); } }