Lots of unexpected “Cannot retrieve value using th

2019-07-12 14:33发布

问题:

When debugging my wpf project I see a lot of binding errors logged in the output window like this one:

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=AreRowDetailsFrozen; DataItem=null; target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')

I googled a lot about this kind of message and tried to fix all my bindings, but the errors keep occuring for properties I never even heard about.

So I broke this down to a basic example:

xaml:

<StackPanel>
    <DataGrid ItemsSource="{Binding Items}" x:Name="_grid" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID, FallbackValue=0}"/>
            <DataGridTextColumn Header="Text" Binding="{Binding Text, FallbackValue={x:Null}}"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button Click="Button_OnClick">Reset</Button>
</StackPanel>

Code behind:

public partial class MainWindow
{
    public ObservableCollection<TestItem> Items { get; } = new ObservableCollection<TestItem>();    
    public MainWindow()
    {
        Items.Add(new TestItem { ID = 1, Text = "One" });
        Items.Add(new TestItem { ID = 2, Text = "Two" });
        InitializeComponent();
    }
    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        _grid.ItemsSource = null;
        _grid.ItemsSource = Items;
    }
}

public class TestItem
{
    public int ID { get; set; }
    public string Text { get; set; }
}

The two elements are displayed correctly in the DataGrid.

Now whenever I click the button (and reassign the ItemSource) I see these 12 messages in the output window:

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=AreRowDetailsFrozen; DataItem=null; target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HeadersVisibility; DataItem=null; target element is 'DataGridRowHeader' (Name=''); target property is 'Visibility' (type 'Visibility')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ID; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Text; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ValidationErrorTemplate; DataItem=null; target element is 'Control' (Name=''); target property is 'Template' (type 'ControlTemplate')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=(0); DataItem=null; target element is 'Control' (Name=''); target property is 'Visibility' (type 'Visibility')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=AreRowDetailsFrozen; DataItem=null; target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HeadersVisibility; DataItem=null; target element is 'DataGridRowHeader' (Name=''); target property is 'Visibility' (type 'Visibility')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ID; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Text; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ValidationErrorTemplate; DataItem=null; target element is 'Control' (Name=''); target property is 'Template' (type 'ControlTemplate')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=(0); DataItem=null; target element is 'Control' (Name=''); target property is 'Visibility' (type 'Visibility')

I checked that the errors appear when setting ItemSource back to Items, not when setting to null. And the number of error messages depends on the number of items in the collection.

I am concerned that these "binding errors" will slow down my real application (where I may have >50k elements in the collection) and therefor want to understand why they appear and how I can avoid them.

As you can see I already added fallback values to my bindings, but the errors keep appearing for properties I didn't bind at all.

回答1:

These binding errors are harmless and it's not much you can do to get rid of them besides modifying the default templates of the elements that make up the DataGrid, and that would not only require quite an effort but it may also lose you some of the built-in functionality of the control.

You should obviously avoid binding errors that you are responsible for yourself but when it comes to binding errors that you "inherit" from the framework without customizing any templates, you can safely just ignore them. Most of these binding errors are both harmless and already handled internally. So just ignore them and do nothing or suppress them. Please refer to the following link for more information.

Resolving harmless binding errors in WPF: https://weblogs.asp.net/akjoshi/resolving-un-harmful-binding-errors-in-wpf