3
votes

Trying to use grouping in DataGrid and for no reasons getting those binding errors (they are not belong to my code, nor I see a way to deal with them):

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=AreRowDetailsFrozen; DataItem=null; target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')

and

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=HeadersVisibility; DataItem=null; target element is 'DataGridRowHeader' (Name=''); target property is 'Visibility' (type 'Visibility')

They appears for each row in DataGrid. This bugs me alot!

To reproduce the problem I made a small project

public class MyItem
{
    public string A { get; set; }
}

public class ViewModel
{
    public List<MyItem> List { get; set; }

    public ViewModel()
    {
        List = new List<MyItem>(new[] { new MyItem() });
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

xaml

<DataGrid ItemsSource="{Binding List}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding A}" Header="A"/>
    </DataGrid.Columns>
    <DataGrid.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="GroupItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="GroupItem">
                                <!-- anything or nothing here -->
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </DataGrid.GroupStyle>
</DataGrid>

Some observations:

  • without DataGrid.GroupStyle there are no errors;
  • with AutoGenerateColumns = true there are no errors;
  • without binding (setting DataGrid.ItemsSource directly) there are no errors.

Only combination of opposite to those 3 conditions will start spamming Output window with above messages.

What should I do? I can't ignore errors, nor I see a way to fix them.

Googling around wasn't really helpful, to example, this case was called a bug, I tried to apply its workarounds, but none works for me.

P.S.: discovering such bugs at first attempt to use DataGrid is very demotivating.


Trying to deal with second error.

<DataGrid.RowHeaderStyle>
    <Style TargetType="DataGridRowHeader">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Setter Property="Template" Value="{x:Null}"/>
    </Style>
</DataGrid.RowHeaderStyle>

But error still

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=HeadersVisibility; DataItem=null; target element is 'DataGridRowHeader' (Name=''); target property is 'Visibility' (type 'Visibility')

2

2 Answers

4
votes

Was playing with control templates and after changing one for DataGridRow errors are gone!

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridRow">
                    <Border BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="DGR_Border" SnapsToDevicePixels="True">
                        <SelectiveScrollingGrid>
                            <DataGridCellsPresenter ItemsPanel="{TemplateBinding ItemsControl.ItemsPanel}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
                        </SelectiveScrollingGrid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowStyle>

I removed DataGridDetailsPresenter and DataGridRowHeader from default template, because I will not use them.


I got one more error

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=NewItemMargin; DataItem=null; target element is 'DataGridRow' (Name=''); target property is 'Margin' (type 'Thickness')

which I fix by adding Margin setter into DataGrid.RowStyle

<Setter Property="Margin" Value="0"/>

It seems all of such errors can be fixed by re-factoring default templates.

0
votes

Firs of all thanks Sinatr for the problem analysis and the solution, which almost worked for me. I did have the same problem with the DataGrid Control. Apart from the binding errors in the output there was a slight displacement of the new item row (in my case the DataRowMargin was off by two DIPs).

DataGridRow invalid margin

The whole issue is caused by a style trigger activated when the IsNewItemProperty equals true, the DataGridRow is not getting the proper margin values. The answer from Sinatr did fix the binding issue but the wrong margin was still used. This is the styling that removed the binding errors and set the correct margin.

<Style TargetType="DataGridRow">
    <Setter Property="Margin" Value="0,0,0,0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridRow">
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="DGR_Border" SnapsToDevicePixels="True">
                    <SelectiveScrollingGrid>
                        <DataGridCellsPresenter ItemsPanel="{TemplateBinding ItemsControl.ItemsPanel}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
                    </SelectiveScrollingGrid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsNewItem" Value="True">
            <Setter Property="Margin" Value="1,0,0,0"/>
        </Trigger>
    </Style.Triggers>
</Style>