WPF数据表格 [System.Windows.Data错误:4]

5

我有一个WPF应用程序,其中包含一个如下所示的DataGrid

Datagrid(简化):

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

当数据加载时,我会收到以下错误信息(多次):
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')

我不知道为什么会发生这种情况,也不知道如何修复它。

编辑:(关于CoreServiceLogViewCollection的信息)

CoreServiceCollection只是ListCollectionView。

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

            return _coreServiceCollection;
        }
    }

该参数只是一个包含ID时间戳和其他属性的ObservableCollection

更新2: 实例化是在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>

请问您能否发布一下您在CoreServiceCollection中的内容? - mchicago
我可以上传更多,但我不认为问题在于集合中。 - RayOldProf
那么你在哪里创建CoreServiceLogViewCollection的实例?它是在XAML资源中被实例化还是已经附加到数据上下文中了? - mchicago
1
看起来样式有些问题。 - user1064519
1
我之前写过一个关于如何读取WPF绑定错误的回答。看起来你的错误信息显示DataGridDetailsPresenter.SelectiveScrollingOrientationDataGridRowHeader.Visibility绑定出现问题,但是在你的XAML代码中我没有找到这两个属性。你能贴出你完整的DataGrid代码吗?如果你为某些DataGrid的部分自定义了样式,请也一并贴出。 - Rachel
显示剩余3条评论
4个回答

14

我之前曾写过一篇关于如何阅读WPF绑定错误的答案。基本上,将错误分解为分号并从下往上阅读它,这应该能够给您一些提示,绑定错误在哪里:

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

从下往上阅读,第一个错误告诉您:

  • 包含引起错误的绑定的属性是SelectiveScrollingOrientation
  • 包含有问题属性的UI对象是DataGridDetailsPresenter,没有指定名称
  • UI对象背后的DataContextnull
  • 绑定尝试查找DataGrid类型的RelativeSource,以便将其绑定到AreRowDetailsFrozen属性,并且无法找到该RelativeSource

因此,请在您的代码中查找类似于以下内容的内容:

<DataGridDetailsPresenter SelectiveScrollingOrientation="{Binding 
    Path=AreRowDetailsFrozen, 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}" />
第二个错误提示您:
- 导致错误的绑定所包含的属性是“Visibility”; - 包含有问题属性的 UI 对象是未指定名称的“DataGridRowHeader”; - UI 对象背后的“DataContext”为 null; - 绑定尝试查找类型为“DataGrid”的“RelativeSource”,以便将其绑定到“HeadersVisibility”属性,并且无法找到该“RelativeSource”。
因此,请查看您的代码是否类似于以下内容:
<DataGridRowHeader Visibility="{Binding 
    Path=HeadersVisibility, 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}" />

根据您发布的代码,第一个可能位于您的 LeftScrollViewer 样式中的某个位置,而第二个可能位于您的 DatagridColumnHeaderCustomTemplateStyle 中。

如果您在 XAML 中遇到问题,请尝试运行应用程序并使用像 Snoop 这样的工具进行检查。这将允许您在 WPF 应用程序运行时查看 VisualTree,并且您应该能够在其中找到确切的绑定错误,从而可以追溯到 XAML 中的源。


2
这是几年前的事情了,但对我来说错误仍然存在——但是:1)我的XAML中没有任何“DataGridRowHeader”或“DataGridDetailsPresenter”的实例——没有;2)它总是发生在某些项目集合上,但从未发生在其他项目集合上;3)当我运行Snoop时,它根本不会发生。也许这是最新的VS 2019 16.6版本的缺陷?欢迎提出想法... - AdvApp
@IronRod 最好提出一个新问题,附上你正在使用的具体XAML和你遇到的错误。希望你能找到解决方案! - Rachel

1
这个错误出现在包含DataGridRowHeader和DataGridDetailsPresenter绑定的DataGridRow的ControlTemplate中。我在.NET 4.5 DataGrid中遇到了同样的问题。似乎只有当DataGrid对其项使用虚拟化时,才会发生这两个错误,您可以尝试在DataGrid中禁用它。我认为当DataGridRow在虚拟化期间以某种方式附加/分离到其DataGrid并且绑定然后丢失或仍然找不到与DataGrid相关的绑定目标时,就会发生这种情况。

将DataGrid.EnableRowVirtualization设置为False似乎可以解决绑定错误。 - Rye bread

0

我有一个包含嵌套 DataGrid 行详情的 DataGrid。我花了很长时间寻找正确的解决方法。

问题出现在 DataGridRow 模板中。 只需搜索“DataGrid 样式和模板”并打开微软网站。

如果你在那里查找 DataGridRow 模板(文本): DataGridRow 的样式和模板。

你会在那里找到这个代码:

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

问题就在这里。

在寻找解决方案时,我发现了这个建议-通过以下方式更改DataGridRow的样式:

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

它起作用了,但我的行细节消失了。在我从原始模板中添加了缺失的部分之后:

 <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}}}"/>

我又遇到了这些错误。所以目标是更改这部分:

<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}}}"/>

将值固定为这样:

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

或者您可以给您的DataGrid命名,然后像这样做:

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

请注意,我已删除 RowHeaders 部分,因为我不使用它。

0

对于在数据表格上使用筛选的人:

我在我的数据表格上使用了 GroupStyle,而且不得不添加

DataGrid.GroupStyle.Clear();

在过滤并添加筛选后的项目之前。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接