无法找到参考“RelativeSource FindAncestor”进行绑定的源

Ber*_*tAR 7 data-binding wpf xaml

我正在使用复合集合:

  • 内容为“选择供应商”的组合框项
  • 绑定到 Vendor 对象的 Observable 集合的 Collection 容器

所需的功能:用户必须从组合框中选择供应商。选择“选择供应商”会将视图模型中的 Vendor 属性设置为 null。

我收到绑定错误。任何想法如何解决这一问题?

调试时出错

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 'ComboBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')
Run Code Online (Sandbox Code Playgroud)

XAML

<ComboBox Name='cmbVendor'
            SelectedItem='{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}'
            IsSynchronizedWithCurrentItem='True'>
    <ComboBox.Resources>
      <CollectionViewSource x:Key='VendorsCollection'
                            Source='{Binding Vendors}' />
      <DataTemplate DataType='{x:Type ComboBoxItem}'>
        <TextBlock Text='{Binding Content}' />
      </DataTemplate>
      <DataTemplate DataType='{x:Type objects:Vendor}'>
        <StackPanel>
          <TextBlock Text='{Binding Name}' />
        </StackPanel>
      </DataTemplate>
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
      <CompositeCollection>
        <ComboBoxItem Content='Select a vendor' />
        <CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
      </CompositeCollection>
    </ComboBox.ItemsSource>
  </ComboBox>
Run Code Online (Sandbox Code Playgroud)

组合框转换器

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

      var vendor = value as Vendor;
        if (vendor != null)
        {
            return vendor;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var vendor = value as Vendor;
        if (vendor != null)
        {
            return vendor;
        }

        var comboboxItem = value as ComboBoxItem;
        if (comboboxItem != null)
        {
            return null;
        }
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

Nie*_*elW 10

添加到您的 App.xaml

<Style TargetType="{x:Type ComboBoxItem}">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
Run Code Online (Sandbox Code Playgroud)


小智 6

默认情况下,ComboBox(和其他 WPF 控件)使用 VirtualizingPanel 作为 ItemsPanel。如果将项目面板更改为不是 VirtualizingPanel,或者将 VirtualizingPanel.IsVirtualizing 附加属性设置为 false,则不会看到此运行时错误。

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True"
          VirtualizingPanel.IsVirtualizing="False">
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

或者

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

这对我有用,而不是仅仅忽略运行时错误。我还尝试将 VirtualizingStackPanel 的 VirtualizationMode 属性更改为 Standard 和 Recycling,但这没有任何效果,并且仍然出现运行时错误。

最后,如果您确实需要虚拟化,因为您的 ComboBox 可能包含许多项目(例如 100 个),那么我建议覆盖 ComboBoxItem 的样式或模板并显式设置 Horizo​​ntalContentAlignment 和 VerticalContentAlignment 属性。

您可以在 Visual Studio 的 XAML 设计器中执行此操作,方法是在“文档大纲”窗口中选择 ComboBox,然后右键单击 ComboBox 节点并选择“编辑其他模板...编辑生成的项容器 (ItemContainerStyle)”。然后更改这两个属性的生成样式:

<Style TargetType="{x:Type ComboBoxItem}">
    ...
    <Setter Property="HorizontalContentAlignment"
            Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    <Setter Property="VerticalContentAlignment"
            Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    ...
</Style>
Run Code Online (Sandbox Code Playgroud)

对此或任何你想要的:

<Style TargetType="{x:Type ComboBoxItem}">
    ...
    <Setter Property="HorizontalContentAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Stretch" />
    ...
</Style>
Run Code Online (Sandbox Code Playgroud)


mm8*_*mm8 1

这些绑定错误是无害的并在内部处理,因此您可以安全地忽略它们或抑制它们。请参阅以下链接了解更多信息。

解决 WPF 中的无害绑定错误: https://weblogs.asp.net/akjoshi/resolving-un-harmful-binding-errors-in-wpf

  • 它们可能是无害的,但会减慢调试模式,同时它们都会吐出 (10认同)