【问题标题】:Cannot find source for binding with reference 'RelativeSource FindAncestor找不到与引用'RelativeSource FindAncestor'绑定的源
【发布时间】:2017-11-20 11:30:48
【问题描述】:

我正在使用复合集合:

  • 内容为“选择供应商”的 Comboboxitem
  • Collectioncontainer 绑定到供应商对象的 Observablecollection

所需的功能:用户必须从组合框中选择供应商。选择“选择供应商”会将视图模型中的供应商属性设置为 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')

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

【问题讨论】:

    标签: wpf xaml data-binding


    【解决方案1】:

    添加到您的 App.xaml

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

    【讨论】:

      【解决方案2】:

      默认情况下,ComboBox(和其他 WPF 控件)为 ItemsPanel 使用 VirtualizingPanel。如果您将项目面板更改为不是 VirtualizingPanel,或者将 VirtualizingPanel.IsVirtualizing 附加属性设置为 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 并明确设置 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>
      

      到这个或任何你想要的:

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level = System.Diagnostics.SourceLevels.Critical 有帮助,但一般会抑制所有数据绑定错误
        • 要么就是这样,要么忽略这些警告。如前所述,它们是无害的,由框架处理。
        • 它们可能无害,但会在它们全部吐出时减慢调试模式
        • 当您有客户使用您的代码时,这不是一个有效的解决方案。
        【解决方案4】:

        添加到您的 App.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}"/>
        

        【讨论】:

          猜你喜欢
          • 2018-09-01
          • 1970-01-01
          • 2013-03-07
          • 2016-04-08
          • 2012-08-16
          • 2011-04-23
          • 2011-01-18
          • 2011-03-12
          • 1970-01-01
          相关资源
          最近更新 更多