ListBoxItem产生“System.Windows.Data Error: 4”绑定错误。

35

我已创建了以下ListBox

<ListBox x:Name="RecentItemsListBox" Grid.Row="1" BorderThickness="0" Margin="2,0,0,0" SelectionChanged="RecentItemsListBox_SelectionChanged">
  <ListBox.Resources>
      <Style TargetType="{x:Type ListBoxItem}"
             BasedOn="{StaticResource {x:Type ListBoxItem}}">
          <Style.Triggers>
              <!--This trigger is needed, because RelativeSource binding can only succeeds if the current ListBoxItem is already connected to its visual parent-->
              <Trigger Property="IsVisible" Value="True">
                  <Setter Property="HorizontalContentAlignment"
                          Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                  <Setter Property="VerticalContentAlignment"
                          Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
              </Trigger>
          </Style.Triggers>
      </Style>
  </ListBox.Resources>
  <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="0,2,0,0">
                <TextBlock Text="{Binding Number}" />
                <StackPanel Orientation="Vertical" Margin="7,0,0,0">
                    <TextBlock Text="{Binding File}" />
                    <TextBlock Text="{Binding Dir}" Foreground="DarkGray" />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这将在运行时在VisualStudio的OutputWindow中产生以下行:

System.Windows.Data Error: 4 : 
 Cannot find source for binding with reference 'RelativeSource FindAncestor, 
 AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. 
 BindingExpression:Path=HorizontalContentAlignment; DataItem=null; 
 target element is 'ListBoxItem' (Name='');

有人能给我一些提示,我该如何解决这个问题?

更新:

我已经将属性添加到样式中,试图消除警告/错误。


你真的需要那种样式吗?为什么不能在DataTemplate中设置StackPanel/TextBlock的对齐方式呢? - John Gardner
5个回答

57

最简单的解决方法是确保你的Listbox拥有ItemContainerStyle。参考以下示例:

<ListBox x:Name="RecentItemsListBox" Grid.Row="1" BorderThickness="0" Margin="2,0,0,0" SelectionChanged="RecentItemsListBox_SelectionChanged">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
        </Style>
    </ListBox.ItemContainerStyle>

...

</ListBox>

发生的情况是,您的Items正在被创建,默认情况下它们查找父项属性,但该属性未定义。显式定义将解决此问题。

我在使用TreeView时遇到了同样的问题,更改这些模板的绑定源会导致这些警告。


27

这里的答案解决了我的问题:

ListBox with Grid as ItemsPanelTemplate produces weird binding errors

在App.xaml(我的应用程序)中定义一个顶级样式,针对“fixed”类型的问题可以解决此问题。以下是适用于您的样式:

<Style TargetType="{x:Type ListBoxItem}">
     <Setter Property="HorizontalContentAlignment" Value="Left" />
     <Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
在我的情况下,我创建了一些TreeViewItems,然后将我的TreeView绑定到创建的items上。绑定错误发生是因为TreeViewItem的绑定在它们被添加到TreeView之前就已经被解析了。正确的解决方案是不要创建TreeViewItem,而是创建一个包含所需数据(Header和Items)的类。只是分享我的情况,以防与您自己的情况有相似之处。

1

对我来说,罪魁祸首是TreeView,而不是ListView。我按照@bsegraves的建议将全局样式添加到了我的App.xaml中:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
</Style>

我还需要在我的TreeView中添加以下内容:

<TreeView.ItemContainerStyle>
    <Style
        BasedOn="{StaticResource {x:Type TreeViewItem}}"
        TargetType="{x:Type TreeViewItem}">         
    </Style>
</TreeView.ItemContainerStyle>

由于某些原因,BasedOn 属性是缺失的关键部分。(我尝试了 @Etienne 的方法,但它没有起作用。)

0

对我而言,另一个可行的解决方法是通过在类或顶级窗口的构造函数中将数据绑定源开关级别设置为关键来抑制这些错误(实际上,更适合称之为警告) -

#if DEBUG     
    System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
        System.Diagnostics.SourceLevels.Critical;
#endif

参考:如何抑制System.Windows.Data错误警告消息

更新:这不是最好的解决方案,但对于有害的警告来说,我认为这看起来不错。


在这里发布了关于此的博客 - http://weblogs.asp.net/akjoshi/archive/2011/11/30/resolving-un-harmful-binding-errors-in-wpf.aspx - akjoshi
19
这是一个不好的想法。首先,这些错误只在Visual Studio中显示,所以它不会展示给用户看。其次,你会隐藏错误。错误是有原因存在的,隐藏它(以及所有相关错误)很可能会在长期内对你造成更多的损失。修复错误,而不是隐藏它! - Peter Drier
1
我有点不同意。我们是成年人,可以记得我们已经暂时禁用了错误,并在我们的应用程序需要时重新审视这些问题。您可以将错误视为对本来可能是粗糙但有用的WPF协变的过度警告:您可以将ListView行绑定到一个较少派生的对象,并且很好地拥有那些运行时对象没有的字段为空白。 - Glenn Slayden
仅仅因为一个场景会输出错误信息,就把错误信息整体隐藏起来似乎是不正确的。 - Epirocks

0

这些 HorizontalContentAlignmentVerticalContentAlignment 的问题是由于容器没有分别定义其 HorizontalAlignmentVerticalAlignment 导致的。

因此,我并非为 ListBoxItemTreeViewItem 或更糟糕的是详尽地直接设置这些属性而制作通用样式,而是在我的 App.xaml 中为 ItemsControl 制作了一个通用样式来解决导致这个问题的任何东西:

<Style TargetType="{x:Type ItemsControl}">
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Top" />
</Style>

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