wpf 找不到与引用“RelativeSource FindAncestor”绑定的源

qqrboqgw  于 2023-03-04  发布在  其他
关注(0)|答案(5)|浏览(386)

我正在使用复合集合:

  • 带有内容“选择供应商”的组合框项
  • 集合容器绑定到供应商对象的Observablecollection

所需功能:用户必须从组合框中选择一个供应商。2选择“选择供应商”会将视图模型中的供应商属性设置为空。
我得到一个绑定错误。任何想法如何解决这个问题?

调试时出错

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

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>

组合框转换器

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;
    }
mrfwxfqh

mrfwxfqh1#

添加到您的应用程序.xaml

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

nue99wik2#

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

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True"
          VirtualizingPanel.IsVirtualizing="False">
</ComboBox>

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

这对我来说是有效的,而不是仅仅忽略运行时错误。我还尝试将VirtualizingStackPanel的VirtualizationMode属性更改为Standard和Recycling,但没有任何效果,运行时错误仍然发生。
最后,如果您确实需要虚拟化,因为您的ComboBox可能包含许多项(例如,100个),那么我建议覆盖ComboBoxItem的Style或Template,并显式设置HorizontalContentAlignment和VerticalContentAlignment属性。
您可以在Visual Studio的XAML设计器中执行此操作,方法是:在“文档大纲”窗口中选择组合框,然后右键单击该组合框节点并选择“* 编辑其他模板...编辑生成的项容器(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>

到这个或任何你喜欢的

<Style TargetType="{x:Type ComboBoxItem}">
    ...
    <Setter Property="HorizontalContentAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Stretch" />
    ...
</Style>
b5buobof

b5buobof3#

我得到了一个类似的问题,但当通过默认样式覆盖ComboBoxItem模板时。
我想为我的组合框/组合框项目有一个自定义模板,所以我覆盖了组合框样式及其模板,并在其中设置了ItemContainerStyle(显然是组合框项目样式)来覆盖和应用自定义样式(然后在其中设置模板)。
代码如下所示:

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <!-- insert the combobox template -->
            </ControlTemplate>
        </Setter.Value>
    </Setter> 
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="ComboBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ComboBoxItem">
                            <!-- insert your comboboxitem template -->
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>
f45qwnt8

f45qwnt84#

这些绑定错误是无害的,并在内部处理,因此您可以安全地忽略或隐藏它们。有关详细信息,请参阅以下链接。

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

polhcujo

polhcujo5#

添加到您的应用程序. xaml

<!-- https://stackoverflow.com/questions/47391020/cannot-find-source-for-binding-with-reference-relativesource-findancestor -->
<Style 
    x:Key="BugFreeListViewItemStyle"
    TargetType="{x:Type ListViewItem}"
    >
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top"/>
</Style>

并使用它:

<ListView ItemContainerStyle="{StaticResource BugFreeListViewItemStyle}"/>

相关问题