public void ObservableExpressionCallsTest() { CallsTestElement element = new CallsTestElement(); element.Value = 1; Assert.AreEqual(0, element.ValueGetterCallsCount); Assert.AreEqual(1, element.ValueSetterCallsCount); ObservableExpression observer = new ObservableExpression(element, "Value"); Assert.AreEqual(1, element.ValueGetterCallsCount); Assert.AreEqual(1, element.ValueSetterCallsCount); Assert.AreEqual(1, observer.Value); Assert.IsTrue(observer.TrySetValue(2)); Assert.AreEqual(2, element.ValueGetterCallsCount); Assert.AreEqual(2, element.ValueSetterCallsCount); Assert.AreEqual(2, observer.Value); Assert.IsTrue(observer.TrySetValue(2)); Assert.AreEqual(2, element.ValueGetterCallsCount); Assert.AreEqual(2, element.ValueSetterCallsCount); Assert.AreEqual(2, observer.Value); Assert.IsTrue(observer.TrySetValue(3)); Assert.AreEqual(3, element.ValueGetterCallsCount); Assert.AreEqual(3, element.ValueSetterCallsCount); Assert.AreEqual(3, observer.Value); }
public BindingExpression(DependencyObject target, DependencyProperty targetProperty, PropertyPath path, object source = null, RelativeSource relativeSource = null, string elementName = null, BindingMode mode = BindingMode.Default, UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default, IValueConverter converter = null, object converterParameter = null, object fallbackValue = null, object targetNullValue = null) { this.Target = target; this.TargetProperty = targetProperty; this.Path = path; this.Source = source; this.RelativeSource = relativeSource; this.ElementName = elementName; this.Mode = mode; this.UpdateSourceTrigger = updateSourceTrigger; this.Converter = converter; this.ConverterParameter = converterParameter; this.FallbackValue = fallbackValue; this.TargetNullValue = targetNullValue; Status = BindingStatus.Inactive; disableSourceUpdate = new ReentrancyLock(); disableTargetUpdate = new ReentrancyLock(); targetValue = new ObservableValue(Target.GetValue(TargetProperty)); targetValue.ValueChanged += OnTargetValueChanged; BindingMode resolvedBindingMode = Mode == BindingMode.Default ? GetDefaultBindingMode(Target, TargetProperty) : Mode; isSourceUpdateMode = resolvedBindingMode == BindingMode.TwoWay || resolvedBindingMode == BindingMode.OneWayToSource; isTargetUpdateMode = resolvedBindingMode == BindingMode.TwoWay || resolvedBindingMode == BindingMode.OneWay; sourceObserver = CreateSourceObserver(Target, Source, RelativeSource, ElementName); sourceExpression = new ObservableExpression(sourceObserver, Path ?? PropertyPath.Empty); // try to update the target (or the source on OneWayToSource) if (isTargetUpdateMode) { sourceExpression.ValueChanged += (sender, oldValue, newValue) => UpdateTargetOnSourceChanged(); UpdateTargetOnSourceChanged(); } else if (isSourceUpdateMode) { sourceExpression.ValueChanged += (sender, oldValue, newValue) => { if (Status == BindingStatus.UpdateSourceError && sourceExpression.Value != ObservableValue.UnsetValue && !disableTargetUpdate) { // source was connected UpdateSourceOnTargetChanged(); } }; UpdateSourceOnTargetChanged(); } if (UpdateSourceTrigger == UpdateSourceTrigger.LostFocus && isSourceUpdateMode && Target is UIElement) { ((UIElement)Target).LostFocus += OnLostFocus; } }
public ObservableExpression(object baseValue, PropertyPath propertyPath) { observableValue = new ObservableValue(); observableValue.ValueChanged += (sender, e) => ValueChanged.Raise(this, e); if (propertyPath.IsEmpty) { observableValue.Value = baseValue; ValueType = baseValue != null ? baseValue.GetType() : null; } else { propertyPathElement = propertyPath.Elements.Last(); baseObserver = new ObservableExpression(baseValue, propertyPath.GetBasePropertyPath()); baseObserver.ValueChanged += (sender, e) => SetDelegateObserverBaseValue(); SetDelegateObserverBaseValue(); } }
public ObservableExpression(object baseValue, PropertyPath propertyPath) { observableValue = new ObservableValue(); observableValue.ValueChanged += (sender, e) => ValueChanged.Raise(this, e); if (propertyPath.IsEmpty) { observableValue.Value = baseValue; ValueType = baseValue != null?baseValue.GetType() : null; } else { propertyPathElement = propertyPath.Elements.Last(); baseObserver = new ObservableExpression(baseValue, propertyPath.GetBasePropertyPath()); baseObserver.ValueChanged += (sender, e) => SetDelegateObserverBaseValue(); SetDelegateObserverBaseValue(); } }
public void ObservableExpressionClrPropertyTest() { ObservableNode child1 = new ObservableNode { Value = 1 }; ObservableNode child2 = new ObservableNode { Value = 2 }; ObservableNode root = new ObservableNode { Value = 0 }; int valueChangedCount = 0; ObservableExpression observableExpression = new ObservableExpression(root, "Child.Value"); observableExpression.ValueChanged += (sender, e) => valueChangedCount++; Assert.AreEqual(ObservableValue.UnsetValue, observableExpression.Value); root.Child = child1; Assert.AreEqual(1, observableExpression.Value); Assert.AreEqual(1, valueChangedCount); child1.Value = 2; Assert.AreEqual(2, observableExpression.Value); Assert.AreEqual(2, valueChangedCount); root.Child = child2; Assert.AreEqual(2, observableExpression.Value); Assert.AreEqual(2, valueChangedCount); child1.Value = 3; Assert.AreEqual(2, observableExpression.Value); Assert.AreEqual(2, valueChangedCount); child2.Value = 3; Assert.AreEqual(3, observableExpression.Value); Assert.AreEqual(3, valueChangedCount); Assert.AreEqual(true, observableExpression.TrySetValue(4)); Assert.AreEqual(3, child1.Value); Assert.AreEqual(4, child2.Value); Assert.AreEqual(4, valueChangedCount); root.Child = null; Assert.AreEqual(ObservableValue.UnsetValue, observableExpression.Value); Assert.AreEqual(5, valueChangedCount); observableExpression.Dispose(); root.Child = child1; Assert.AreEqual(5, valueChangedCount); }
public void ObservableExpressionIndexerTest() { ObservableNode root = new ObservableNode { Children = new ObservableCollection<ObservableNode> { new ObservableNode { Value = 1 } } }; int valueChanged = 0; ObservableExpression observableExpression = new ObservableExpression(root, "Children[0].Value"); observableExpression.ValueChanged += (sender, e) => valueChanged++; Assert.AreEqual(1, observableExpression.Value); Assert.AreEqual(0, valueChanged); root.Children[0].Value = 2; Assert.AreEqual(2, observableExpression.Value); Assert.AreEqual(1, valueChanged); root.Children[0] = new ObservableNode { Value = 3 }; Assert.AreEqual(3, observableExpression.Value); Assert.AreEqual(2, valueChanged); root.Children = new ObservableCollection<ObservableNode> { new ObservableNode { Value = 4 } }; Assert.AreEqual(4, observableExpression.Value); Assert.AreEqual(3, valueChanged); root.Children[0] = new ObservableNode { Value = 4 }; Assert.AreEqual(4, observableExpression.Value); Assert.AreEqual(3, valueChanged); root.Children = new ObservableCollection<ObservableNode> { new ObservableNode { Value = 4 } }; Assert.AreEqual(4, observableExpression.Value); Assert.AreEqual(3, valueChanged); root.Children.Add(new ObservableNode { Value = 5 }); Assert.AreEqual(4, observableExpression.Value); Assert.AreEqual(3, valueChanged); root.Children.RemoveAt(0); Assert.AreEqual(5, observableExpression.Value); Assert.AreEqual(4, valueChanged); observableExpression.Dispose(); root.Children[0].Value = 6; Assert.AreEqual(4, valueChanged); }
public void ObservableExpressionHybridPropertyTest() { DependencyObjectNode child = new DependencyObjectNode(); ObservableNode observableChild = new ObservableNode { Value = 1 }; DependencyObjectNode root = new DependencyObjectNode { Value_ClrWrapper = 0 }; int valueChangedCount = 0; ObservableExpression observer = new ObservableExpression(root, "Child.ObservableChild.Value"); observer.ValueChanged += (sender, e) => valueChangedCount++; Assert.AreEqual(ObservableValue.UnsetValue, observer.Value); root.Child_ClrWrapper = child; child.ObservableChild_ClrWrapper = observableChild; Assert.AreEqual(1, observer.Value); Assert.AreEqual(1, valueChangedCount); observableChild.Value = 2; Assert.AreEqual(2, observer.Value); Assert.AreEqual(2, valueChangedCount); root.Child_ClrWrapper = null; Assert.AreEqual(ObservableValue.UnsetValue, observer.Value); Assert.AreEqual(3, valueChangedCount); observer.Dispose(); root.Child_ClrWrapper = child; Assert.AreEqual(3, valueChangedCount); }
public void ObservableExpressionCustomIndexerTest() { ObservableNode root = new ObservableNode { ItemValue = 2 }; int valueChanged = 0; ObservableExpression observableExpression1 = new ObservableExpression(root, "Item[3]"); ObservableExpression observableExpression2 = new ObservableExpression(root, "[4]"); observableExpression1.ValueChanged += (sender, e) => valueChanged++; observableExpression2.ValueChanged += (sender, e) => valueChanged++; Assert.AreEqual(6, observableExpression1.Value); Assert.AreEqual(8, observableExpression2.Value); root.ItemValue = 3; Assert.AreEqual(9, observableExpression1.Value); Assert.AreEqual(12, observableExpression2.Value); Assert.AreEqual(2, valueChanged); }
public BindingExpression(DependencyObject target, DependencyProperty targetProperty, PropertyPath path, object source = null, RelativeSource relativeSource = null, string elementName = null, BindingMode mode = BindingMode.Default, UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default, IValueConverter converter = null, object converterParameter = null, object fallbackValue = null, object targetNullValue = null) { this.Target = target; this.TargetProperty = targetProperty; this.Path = path; this.Source = source; this.RelativeSource = relativeSource; this.ElementName = elementName; this.Mode = mode; this.UpdateSourceTrigger = updateSourceTrigger; this.Converter = converter; this.ConverterParameter = converterParameter; this.FallbackValue = fallbackValue; this.TargetNullValue = targetNullValue; Status = BindingStatus.Inactive; disableSourceUpdate = new ReentrancyLock(); disableTargetUpdate = new ReentrancyLock(); targetValue = new ObservableValue(Target.GetValue(TargetProperty)); targetValue.ValueChanged += OnTargetValueChanged; BindingMode resolvedBindingMode = Mode == BindingMode.Default ? GetDefaultBindingMode(Target, TargetProperty) : Mode; isSourceUpdateMode = resolvedBindingMode == BindingMode.TwoWay || resolvedBindingMode == BindingMode.OneWayToSource; isTargetUpdateMode = resolvedBindingMode == BindingMode.TwoWay || resolvedBindingMode == BindingMode.OneWay; object resolvedSource = Source ?? GetRelativeSource(Target, RelativeSource, ElementName); sourceExpression = new ObservableExpression(resolvedSource, Path); // try to update the target (or the source on OneWayToSource) if (isTargetUpdateMode) { sourceExpression.ValueChanged += (sender, e) => UpdateTargetOnSourceChanged(); UpdateTargetOnSourceChanged(); } else if (isSourceUpdateMode) { sourceExpression.ValueChanged += (sender, e) => { if (Status == BindingStatus.UpdateSourceError && sourceExpression.Value != ObservableValue.UnsetValue && !disableTargetUpdate) { // source was connected UpdateSourceOnTargetChanged(); } }; UpdateSourceOnTargetChanged(); } if (((RelativeSource != null && RelativeSource.Mode != RelativeSourceMode.Self) || !ElementName.IsNullOrEmpty()) && Target is Visual) { ((Visual)Target).VisualAncestorChanged += OnTargetVisualAncestorChanged; } if (UpdateSourceTrigger == UpdateSourceTrigger.LostFocus && isSourceUpdateMode && Target is UIElement) { ((UIElement)Target).LostFocus += OnLostFocus; } }