RayOldProf
RayOldProf

Reputation: 1070

WPF Datagrid [System.Windows.Data Error: 4]

I have a WPF application with a DataGrid as shown below:

Datagrid (simplified):

<DataGrid x:Name="CoreServiceLogDataGrid"
Grid.Row="0"
Height="auto"
ItemsSource="{Binding Source={StaticResource CoreServiceCollection}}"
AutoGenerateColumns="False"
CanUserReorderColumns="True"
CanUserSortColumns="True"
IsReadOnly="True">

    <DataGrid.Columns>
        <DataGridTextColumn x:Name="ID"
            Header="ID"
            Binding="{Binding ID}" />

        <DataGridTextColumn Binding="{Binding Timestamp}"
            Header="Timestamp" />

    </DataGrid.Columns>

</DataGrid>

when the Data is loaded; I get the following Error (numerous times):

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')
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')

I have No Idea why this occurs and how to FIX this.

EDIT: (Info about CoreServiceLogViewCollection)

CoreServiceCollection is just a ListCollectionView.

  public static ListCollectionView CoreServiceLogViewCollection {
        get {
            if (_coreServiceCollection == null) {
                _coreServiceCollection =
                    new ListCollectionView(LogSession.CoreServiceLogCollection);
            }

            return _coreServiceCollection;
        }
    }

the parameter is just an ObservableCollection containing ID,Timestamp and other properties

EDIt2: The instantiation is done in App.xaml:

   <ResourceDictionary>
       <x:Static Member="vm2:CoreServiceLogView.CoreServiceLogViewCollection"
                          x:Key="CoreServiceCollection" />
   </ResourceDictionary>

EDIT 3 (The Style... )

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                mc:Ignorable="d">


<!-- #columnHeaderDGStyle -->


<!-- Datagrid -->
<Style x:Key="Log4NetDataGridStyle"
       TargetType="DataGrid">

    <Setter Property="ColumnHeaderStyle"
            Value="{DynamicResource DatagridColumnHeaderCustomTemplateStyle}" />


    <Setter Property="RowStyle"
            Value="{DynamicResource Log4NetRowStyle}" />

    <Setter Property="RowDetailsTemplate"
            Value="{DynamicResource RowDetailsTemplate}" />

    <Setter Property="MaxHeight"
            Value="1600">
    </Setter>
    <Setter Property="MaxWidth"
            Value="2560">
    </Setter>


</Style>


<Style x:Key="DataCommuGridStyle"
       TargetType="DataGrid">

    <Setter Property="ColumnHeaderStyle"
            Value="{DynamicResource DatagridColumnHeaderCustomTemplateStyle}" />


    <Setter Property="RowStyle"
            Value="{DynamicResource CommuRowStyle}" />

    <Setter Property="RowDetailsTemplate"
            Value="{DynamicResource RowDetailsTemplate}" />

    <Setter Property="MaxHeight"
            Value="1600">
    </Setter>
    <Setter Property="MaxWidth"
            Value="2560">
    </Setter>


</Style>


<!-- ************************* Row Style ************************* -->
<Style x:Key="Log4NetRowStyle"
       TargetType="DataGridRow">

    <Setter Property="FontSize"
            Value="14" />

    <Setter Property="Background"
            Value="{Binding Path=LogColour.ColorName}" />

    <Setter Property="Height"
            Value="Auto">
    </Setter>

    <Style.Triggers>
        <DataTrigger></DataTrigger>
    </Style.Triggers>

</Style>

<Style x:Key="CommuRowStyle"
       TargetType="DataGridRow">

    <Setter Property="FontSize"
            Value="14" />

    <Setter Property="Background"
            Value="Azure" />

    <Setter Property="Height"
            Value="Auto">
    </Setter>

    <Style.Triggers>
        <DataTrigger></DataTrigger>
    </Style.Triggers>

</Style>


<DataTemplate x:Key="RowDetailsTemplate">
    <Border BorderThickness="0"
            Padding="5" >


        <Border.Background>
            <LinearGradientBrush StartPoint="0,0"
                                 EndPoint="0,1" Opacity="0.2">
                <GradientStop Color="White"
                              Offset="0" />
                <GradientStop Color="Black"
                              Offset="1" />
            </LinearGradientBrush>

        </Border.Background>


        <!-- alternative with Expancer -->
        <Expander IsExpanded="True"
                  HorizontalAlignment="Left"
                  BorderThickness="1,1,1,5"
                  MaxHeight="300"
                  MaxWidth="900">

            <Expander.Header>
                <DockPanel>
                    <TextBlock FontSize="12"
                               Text="LoggingMessage: "
                               VerticalAlignment="Center" />
                </DockPanel>
            </Expander.Header>

            <Expander.Content>
                <ScrollViewer VerticalScrollBarVisibility="Auto"
                              HorizontalScrollBarVisibility="Auto"
                              CanContentScroll="True"
                              Style="{StaticResource LeftScrollViewer}">
                    <StackPanel Orientation="Vertical">

                        <TextBox FontSize="16"
                                 BorderThickness="0"
                                 IsReadOnly="True"
                                 Background="Transparent"
                                 Foreground="Black"
                                 TextWrapping="Wrap"
                                 Text="{Binding LoggingMessage, Mode=OneWay}" />
                    </StackPanel>
                </ScrollViewer>
            </Expander.Content>
        </Expander>


    </Border>


</DataTemplate>


<Style x:Key="GroupHeaderStyle"
       TargetType="{x:Type GroupItem}">
    <Setter Property="Margin"
            Value="0,0,0,5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type GroupItem}">
                <Expander IsExpanded="False"
                          Background="#FF112255"
                          BorderBrush="#FF002255"
                          Foreground="Black"
                          BorderThickness="1,1,1,5">
                    <Expander.Header>
                        <DockPanel>
                            <TextBlock FontWeight="Bold"
                                       Foreground="White"
                                       Text="{Binding Path=Name}"
                                       Margin="5,0,0,0"
                                       Width="100" />
                            <TextBlock FontWeight="Bold"
                                       Foreground="White"
                                       Text="{Binding Path=ItemCount}" />
                        </DockPanel>
                    </Expander.Header>

                    <Expander.Content>
                        <ItemsPresenter />
                    </Expander.Content>
                </Expander>


            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>


<!-- ******************** DataTemplate ******************** -->


</ResourceDictionary>

Upvotes: 5

Views: 11540

Answers (4)

Egil Sandfeld
Egil Sandfeld

Reputation: 106

For anyone using filtering on their data grids:

I was using GroupStyle on my data grid and had to add

DataGrid.GroupStyle.Clear();

while filtering and before adding the filtered items.

Upvotes: 0

Alex
Alex

Reputation: 13

I have a DataGrid with nested DataGrids as RowDetails. And i also looked for a long time for right answer to solve this problem.

The problem occures in DataGridRow template. Just look for "DataGrid styles and templates" - and open Microsoft site.

If you'll look there for a DataGridRow Template (text): Style and template for the DataGridRow.

You'll find there this code:

 <SelectiveScrollingGrid>
        <SelectiveScrollingGrid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="*" />
        </SelectiveScrollingGrid.ColumnDefinitions>
        <SelectiveScrollingGrid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="Auto" />
        </SelectiveScrollingGrid.RowDefinitions>
        <DataGridCellsPresenter Grid.Column="1"
                                ItemsPanel="{TemplateBinding ItemsPanel}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        <DataGridDetailsPresenter Grid.Column="1"
                                  Grid.Row="1"
                                  Visibility="{TemplateBinding DetailsVisibility}"
                                  SelectiveScrollingGrid.SelectiveScrollingOrientation=
            "{Binding AreRowDetailsFrozen, 
            ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
            Converter={x:Static DataGrid.RowDetailsScrollingConverter}, 
            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
        <DataGridRowHeader Grid.RowSpan="2"
                           SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                           Visibility="{Binding HeadersVisibility, 
            ConverterParameter={x:Static DataGridHeadersVisibility.Row}, 
            Converter={x:Static DataGrid.HeadersVisibilityConverter}, 
            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
      </SelectiveScrollingGrid>

And the problem is here.

In a search for a solution i've found this recomendation - to change style of DataGridRow this way:

  <Style TargetType="{x:Type 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>

It worked, but my row details was gone. After i've added missing part from the original template:

 <SelectiveScrollingGrid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="Auto" />
        </SelectiveScrollingGrid.RowDefinitions>
        <DataGridCellsPresenter Grid.Column="1"
                                ItemsPanel="{TemplateBinding ItemsPanel}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        <DataGridDetailsPresenter Grid.Column="1"
                                  Grid.Row="1"
                                  Visibility="{TemplateBinding DetailsVisibility}"
                                  SelectiveScrollingGrid.SelectiveScrollingOrientation=
            "{Binding AreRowDetailsFrozen, 
            ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
            Converter={x:Static DataGrid.RowDetailsScrollingConverter}, 
            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>

I've got this errors again. So the goal is to change this part:

<DataGridDetailsPresenter Grid.Column="1"
                                  Grid.Row="1"
                                  Visibility="{TemplateBinding DetailsVisibility}"
                                  SelectiveScrollingGrid.SelectiveScrollingOrientation=
            "{Binding AreRowDetailsFrozen, 
            ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
            Converter={x:Static DataGrid.RowDetailsScrollingConverter}, 
            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>

To fixed value, like this:

 <DataGridDetailsPresenter Grid.Column="1"
                                  Grid.Row="1"
                                  Visibility="{TemplateBinding DetailsVisibility}"
                                  SelectiveScrollingGrid.SelectiveScrollingOrientation="Both"/>

Or you can name your DataGrid and do smth like that:

 <SelectiveScrollingGrid>
                                    <SelectiveScrollingGrid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="Auto" />
                                    </SelectiveScrollingGrid.RowDefinitions>
                                    <DataGridCellsPresenter ItemsPanel="{TemplateBinding ItemsControl.ItemsPanel}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
                                    <DataGridDetailsPresenter  Grid.Row="1"
                                    Visibility="{TemplateBinding DetailsVisibility}"
                                    SelectiveScrollingGrid.SelectiveScrollingOrientation=
                                    "{Binding ElementName=MainDataGrid,Path=AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
                                     Converter={x:Static DataGrid.RowDetailsScrollingConverter}}"/>
                                </SelectiveScrollingGrid>

Notice, that i've deleted RowHeaders part as i don't use it.

Upvotes: 1

Michael
Michael

Reputation: 51

This error occures in the ControlTemplate for the DataGridRow that contains both a DataGridRowHeader and a DataGridDetailsPresenter with the bindings mentioned above. I got the same issue for the .NET 4.5 DataGrid. It seems that both errors only occures when the DataGrid is using virtualization for it's items, you can try to disable it in your DataGrid. In my opinion it happens when a DataGridRow is somehow attached/detached from it's DataGrid during the virtualization and the binding then looses or still not find the relative binding targets to the DataGrid.

Upvotes: 1

Rachel
Rachel

Reputation: 132548

I wrote an answer a while back about how to read WPF binding errors. Basically, break down your error on the semi-colons and start reading it from the bottom up, and it should give you some idea where the binding error is:

  • 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')

Reading from the bottom up, the first error is telling you

  • the property containing the binding causing the error is SelectiveScrollingOrientation
  • the UI object containing the problematic property is a DataGridDetailsPresenter, with no name specified
  • the DataContext behind the UI object is null
  • the binding is trying to find a RelativeSource of type DataGrid so it can bind to the AreRowDetailsFrozen property, and its failing to find that RelativeSource

So look through your code for something resembling this:

<DataGridDetailsPresenter SelectiveScrollingOrientation="{Binding 
    Path=AreRowDetailsFrozen, 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}" />

The second error is telling you

  • the property containing the binding causing the error is Visibility
  • the UI object containing the problematic property is a DataGridRowHeader, with no name specified
  • the DataContext behind the UI object is null
  • the binding is trying to find a RelativeSource of type DataGrid so it can bind to the HeadersVisibility property, and its failing to find that RelativeSource

So look through your code for something resembling this:

<DataGridRowHeader Visibility="{Binding 
    Path=HeadersVisibility, 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}" />

Based on the code you posted, the first may be in your LeftScrollViewer style somewhere, and the 2nd is probably in your DatagridColumnHeaderCustomTemplateStyle

If you have problems finding the error in your XAML, you can try running your application and inspecting it with a tool like Snoop that will let you look at the VisualTree of a WPF application while it's running, and you should be able to find the exact binding error there so you can trace it back to the source in your XAML

Upvotes: 14

Related Questions