DependencyProperty doesn't fire ValueChanged when new value is the same

ε祈祈猫儿з 提交于 2019-12-10 01:30:02

问题


Ok so here's the problem: I wrote a UserControl which receives a new value say like every 100ms and does something with it. It has to handle each new value setter, even if the value didn't change. The UserControl has a few DependencyProperties:

public double CurrentValue
    {
        get { return (double)GetValue(CurrentValueProperty); }
        set { SetValue(CurrentValueProperty, value); }
    }

    public static readonly DependencyProperty CurrentValueProperty =
       DependencyProperty.Register("CurrentValue", typeof(double), typeof(GraphControl), new UIPropertyMetadata(0d));

In the XAML where this control is used, I just set the Binding of CurrentValue to a (INotifyPropertyChanged-enabled) property:

<uc:UserControl CurrentValue="{Binding MyValue}" ... />

viewmodel:

    public double MyValue
    {
        get { return _value; }
        set
        {
            //if (_value == value) return;
            _value= value;
            if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("MyValue"));
        }
    }

As you can see, I explicitly commented out the if equals then return so it will fire the PropertyChanged event even when the value gets updated to the same value.

Now back to my user control, I tried registering the ValueChanged in two ways; first by using the DependencyPropertyDescriptor:

var propertyDescriptor = DependencyPropertyDescriptor.FromProperty(CurrentValueProperty, typeof(GraphControl));
propertyDescriptor.AddValueChanged(this, OnCurrentValueChanged);

or by using the UIPropertyMetaData:

new UIPropertyMetadata(0d, OnCurrentValueChangedCallback)

so a stub of the callback would look like:

private void Callback(object sender, EventArgs e){
    //do stuff
}

Ok now the problem is, the callback is not fired when the value doesn't explicitly change. I checked, and the PropertyChanged event is firing in my viewmodel, but the control doesn't see the change. When the value changes to a new value, it will handle the callback as expected.
Is there any way to override this behavior so that my callback method will always get hit?

EDIT:
I also tried using the CoerceValueCallback, and that one is hit when the value stays the same, but it doesn't help me with my problem I think...


回答1:


You can wrap your value up in an object, i.e. create a class to hold it - then set the property to a new instance of that class containing the new value, every time. That means you're creating ~10 objects per second, but they are each different, will trigger the change event, and are only small (will be GC'd anyway). :)




回答2:


Another alternative is to switch the value temporarily to something else then restore the previous one. You can do this entire trick transparently in the Coerce callback as such:

public static readonly DependencyProperty TestProperty = DependencyProperty.Register(
    "Test", typeof(object), typeof(School),
    new PropertyMetadata(null, TestChangedCallback, TestCoerceCallback));

static object TestCoerceCallback(DependencyObject d, object baseValue)
{
    if (baseValue != null && (d.GetValue(TestProperty) == baseValue))
    {
        d.SetCurrentValue(TestProperty, null);
        d.SetCurrentValue(TestProperty, baseValue);
    }
    return baseValue;
}

Just make sure your property code can handle the null value case gracefully.



来源:https://stackoverflow.com/questions/6826914/dependencyproperty-doesnt-fire-valuechanged-when-new-value-is-the-same

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!