DependencyObject.InvalidateProperty not working

后端 未结 3 2006
暖寄归人
暖寄归人 2021-01-11 12:16

Based on the documentation via MSDN...

You can also use InvalidateProperty to force re-evaluation of a binding against a data source that is not a

相关标签:
3条回答
  • 2021-01-11 12:41

    we never got it working either, here's the function which does the trick:

    private void InvalidateProperty(DependencyProperty property,
        FrameworkElement container)
    {
        container.SetBinding(property, 
            container.GetBindingExpression(property).ParentBinding);
    }
    

    And here's how we call it:

    private void Invalidate(object sender, RoutedEventArgs e)
    {
        _payload.Timestamp = DateTime.Now.Add(TimeSpan.FromHours(1)).ToLongTimeString();
    
        Button b = sender as Button;
    
        //b.InvalidateProperty(Button.ContentProperty);
        this.InvalidateProperty(Button.ContentProperty, b);
    }
    

    I also had to set DataContext to _payload.

    0 讨论(0)
  • 2021-01-11 12:49

    As you mentioned, it ought to work but doesn't. But there is a simple workaround:

    // Doesn't work:
    //b.InvalidateProperty(Button.ContentProperty);
    
    // Works:
    BindingOperations.GetBindingExpression(b, Button.ContentProperty).UpdateTarget();
    

    I debugged into the reference source and all InvalidateProperty does in your situation is cause a cached value to be re-read from the BindingExpression into the Button Content property. Offhand, I don't know when this would even be necessary but it's not useful to get the BindingExpression to re-read the raw property.

    Since the workaround is convenient and general, the only further effort warranted is filing a bug report with Microsoft.

    0 讨论(0)
  • 2021-01-11 12:51

    Yes. I have an idea.

    The reason why your code doesn't work is that button asks for new value, but Binding object holds the old one as it hasn't got PropertyChanged notification. The changes chain in standart scenario looks like:

    Payload.Timestamp -> Binding object -> Button.ContentProperty

    In your scenario, when you call InvalidateProperty chain is:

    Binding object -> Button.ContentProperty

    So, you should notify binding object that its source has been changed with next code:

        private void Invalidate(object sender, RoutedEventArgs e)
        {
            _payload.Timestamp = DateTime.Now.Add(TimeSpan.FromHours(1)).ToLongTimeString();
    
            Button b = sender as Button;
            BindingExpression be = b.GetBindingExpression(Button.ContentProperty);
            be.UpdateTarget();
        }
    

    As you can see, I even shouldn't call InvalidateProperty, because the Binding mechanizm due to changed underlying source will automatically force Button to refresh content.

    0 讨论(0)
提交回复
热议问题