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);
        }
Esempio n. 2
0
        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;
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 9
0
        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;
            }
        }