Binding errors from under the hood
Trying to use grouping in DataGrid
and for no reason to get these binding errors (they don't belong in my code and I don't see a way to deal with them):
System.Windows.Data error: 4: Unable to find source for binding with reference 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.DataGrid ', AncestorLevel =' 1 ''. BindingExpression: Path = AreRowDetailsFrozen; DataItem = NULL; the target is "DataGridDetailsPresenter" (Name = ''); target is "SelectiveScrollingOrientation" (type "SelectiveScrollingOrientation")
and
System.Windows.Data error: 4: Unable to find source to bind with reference 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.DataGrid ', AncestorLevel =' 1 ''. BindingExpression: Path = HeadersVisibility; DataItem = NULL; target element - "DataGridRowHeader" (Name = ''); target is "Visibility" (type "Visibility")
They appear for every line in the DataGrid
. This worries me very much!
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:
- no
DataGrid.GroupStyle
mistakes; - with
AutoGenerateColumns = true
no errors; - no linking (installing
DataGrid.ItemsSource
directly) no errors.
Only the combination opposite to these 3 conditions will trigger the mailing list Output
with the above messages.
What should I do? I cannot ignore the errors and I see no way to fix them.
Enabling googling was not really helpful, for example this case was called a bug, I tried to apply its workarounds, but none works for me.
PS: finding such errors on the first try is DataGrid
very demotivating.
Trying to deal with the second error.
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Template" Value="{x:Null}"/>
</Style>
</DataGrid.RowHeaderStyle>
But the error is still
System.Windows.Data error: 4: Unable to find source to bind with reference 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.DataGrid ', AncestorLevel =' 1 ''. BindingExpression: Path = HeadersVisibility; DataItem = NULL; target element - "DataGridRowHeader" (Name = ''); target is "Visibility" (type "Visibility")
source to share
Played with control patterns and after changing one for DataGridRow
errors there was no!
<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 the default template, because I will not use them.
I got another error
System.Windows.Data error: 4: Unable to find source to bind with reference 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.DataGrid ', AncestorLevel =' 1 ''. BindingExpression: Path = NewItemMargin; DataItem = NULL; the target is "DataGridRow" (Name = ''); target property "Margin" (type "Thickness")
which I fix by adding a Margin
setter toDataGrid.RowStyle
<Setter Property="Margin" Value="0"/>
It seems that all such errors can be fixed by re-factoring the default templates.
source to share
Thanks to Sinatr everyone for analyzing the problem and a solution that almost worked for me. I had the same problem with DataGrid Control. Apart from binding errors, there was a slight row offset of the new item in the output (in my case, the DataRowMargin was disabled by two DIPs).
The whole problem is caused by invoking the style when IsNewItemProperty is true, the DataGridRow is not getting the correct field values. The answer from Sinatr did fix the binding issue, but the wrong margin was still being used. This is the style that removes binding errors and sets 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>
source to share