简体   繁体   中英

PropertyChanged event fired but value hasn't changed

I have a custom control dynamically created by another control, I want to change its VisualState based on the VisualState of the parent. VisualState is a DependencyProperty that accept an enumerator, the control internally uses it inside the OnPropertyChange event to change size and internal layout. The property are made identical on both controls (of course except the type).

public ControlSize VisualState
{
    get { return (ControlSize)GetValue(VisualStateProperty); }
    set
    {
        if (value != VisualState)
        {
            SetValue(VisualStateProperty, value);
        }
    }
}

public static readonly DependencyProperty VisualStateProperty = DependencyProperty.RegisterAttached(nameof(VisualState), typeof(ControlSize), typeof(CountersListControl), new PropertyMetadata(ControlSize.Large, OnVisualStateChanged));

The parent control dynamically allocate the component and binds its VisualState to the new control VisualState:

CounterControl cc = new CounterControl();
cc.SetBinding(CounterControl.ValueProperty, new Binding() { Path = new PropertyPath(nameof(Counter.Amount)), Source = counter, Mode = BindingMode.TwoWay });
//cc.DataContext = this;//I tried with it, but it doesn't change a thing
cc.SetBinding(CounterControl.VisualStateProperty, new Binding() { Path = new PropertyPath(nameof(VisualState)), Source = this, Mode = BindingMode.OneWay });

The Value property binds without any issue to Counter.Amount, and looks that VisualState does too.

BUT the OnVisualState method is called when the parent is changed, while the children value is not.

UPDATE: I debugged the binding as suggested by @EdPlunkett, and I was getting the following message:

Error: Converter failed to convert value of type 'Windows.Foundation.Int32' to type 'ControlSize';

ControlSize is an enumerable, so it should be able to convert it.

This happens because somehow it can't convert an Int32 into an enumerable (even if the source is the same enumerable).

I solved creating an IValueConverter that converts Int32/ControlSize types and assigning it to the binding.

Binding visualStateBinding = new Binding() { Path = new PropertyPath(nameof(VisualState)), Source = this, Mode = BindingMode.OneWay, Converter = new ControlSizeConverter() };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM