我有一个列表框控件,我提出在网格布局中一个ListBoxItem对象的固定数目。 所以,我把我的ItemsPanelTemplate是一个网格。
我从代码访问网格的背后配置RowDefinitions和ColumnDefinitions。
到目前为止,我希望一切正常。 我有一些自定义的IValueConverter实现返回的Grid.Row和Grid.Column每一个ListBoxItem应该出现英寸
不过我得到奇怪的绑定错误,有时,我无法弄清楚到底他们为什么发生,或者即使他们是在我的代码。
这是我得到的错误:
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=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
任何人能解释这是怎么回事?
哦,还有,这里是我的XAML:
<UserControl.Resources>
<!-- Value Converters -->
<v:GridRowConverter x:Key="GridRowConverter" />
<v:GridColumnConverter x:Key="GridColumnConverter" />
<v:DevicePositionConverter x:Key="DevicePositionConverter" />
<v:DeviceBackgroundConverter x:Key="DeviceBackgroundConverter" />
<Style x:Key="DeviceContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Grid.Row" Value="{Binding Path=DeviceId, Converter={StaticResource GridRowConverter}}" />
<Setter Property="Grid.Column" Value="{Binding Path=DeviceId, Converter={StaticResource GridColumnConverter}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border CornerRadius="2" BorderThickness="1" BorderBrush="White" Margin="2" Name="Bd"
Background="{Binding Converter={StaticResource DeviceBackgroundConverter}}">
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Path=DeviceId, Converter={StaticResource DevicePositionConverter}}" >
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Property="BorderThickness" Value="2" />
<Setter TargetName="Bd" Property="Margin" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Border CornerRadius="3" BorderThickness="3" Background="#FF333333" BorderBrush="#FF333333" >
<Grid ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Image Margin="20,3,3,3" Source="Barcode.GIF" Width="60" Stretch="Fill" />
</StackPanel>
<ListBox ItemsSource="{Binding}" x:Name="lstDevices" Grid.Row="1"
ItemContainerStyle="{StaticResource DeviceContainerStyle}"
Background="#FF333333"
SelectedItem="{Binding SelectedDeviceResult, ElementName=root, Mode=TwoWay}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.LayoutTransform>
<RotateTransform Angle="90" />
</Grid.LayoutTransform>
</Grid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Border>
Answer 1:
结合问题来自于对ListBoxItem的默认样式。 默认情况下,将样式应用于元素时,WPF查找默认的样式,并应用没有特别从默认风格自定义样式设置每个属性。 请参考这个伟大的博客文章由伊恩·格里菲思有关此行为的更多细节。
回到我们的问题。 下面是ListBoxItem的默认样式:
<Style
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<ResourceDictionary/>
</Style.Resources>
<Setter Property="Panel.Background">
<Setter.Value>
<SolidColorBrush>
#00FFFFFF
</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Control.HorizontalContentAlignment">
<Setter.Value>
<Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
</Setter.Value>
</Setter>
<Setter Property="Control.VerticalContentAlignment">
<Setter.Value>
<Binding Path="VerticalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}"/>
</Setter.Value>
</Setter>
<Setter Property="Control.Padding">
<Setter.Value>
<Thickness>
2,0,0,0
</Thickness>
</Setter.Value>
</Setter>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
请注意,我已经删除了控件模板,使其小巧(我用StyleSnooper -要检索的样式)。 你可以看到,有一个与设置为祖先类型的ItemsControl相对来源的绑定。 所以你的情况是有约束力没有找到他们的ItemsControl时创建的ListBoxItems。 你能提供什么是你的ListBox中的ItemsSource更多信息?
PS:删除错误的一种方法是在您的自定义样式来创建HorizontalContentAlignment和VerticalContentAlignment新制定者。
Answer 2:
设置OverridesDefaultStyle
到True
在你ItemContainerStyle
也将解决这些问题。
<Style TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<!-- set the rest of your setters, including Template, here -->
</Style>
Answer 3:
这是一个常见的问题有ListBoxItem
S和其他短暂*Item
的容器。 他们是异步创建/上的苍蝇,而ItemsControl
加载/渲染。 你必须重视ListBox.ItemContainerGenerator
的StatusChanged
事件和等待状态成为ItemsGenerated
试图访问它们。
Answer 4:
这是这里的其他答案的汞齐,但对我来说,我不得不套用Setter
在两个地方解决错误,虽然这个使用自定义时是VirtualizingWrapPanel
如果我删除下面的任何一个Setter
声明,我的错误再次出现。
<ListView>
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<controls:VirtualizingWrapPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
我真的没有在此刻进一步调查的时间,但我怀疑这是与该JTango提到在他的回答中默认的风格 - 我真的不定制我的模板,以一个巨大的程度。
我认为有更多的里程将出过其他的答案,但我想我会发布此上关的机会,它可以帮助别人在同一条船上。
大卫施密特的回答看起来似乎描述的根本原因。
Answer 5:
我有同样的问题,因为你,我只是想分享什么是我的解决方案。 我已经尝试了所有选项,从这个职位,但最后一个是最适合我 - THX克里斯。
所以,我的代码:
<ListBox.Resources>
<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="24"/>
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource listBoxItemStyle}"/>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Binding Source="{StaticResource listBoxItemStyle}"/>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" IsItemsHost="True" MaxWidth="170"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
我还发现,如果自定义这个错误不会出现ItemsPanelTemplate
不存在。
Answer 6:
我刚刚遇到了同样类型的错误:
System.Windows.Data错误:4:不能用于与参考 '的RelativeSource FindAncestor,AncestorType =' 结合找到源System.Windows.Controls.ItemsControl 'AncestorLevel = '1''。 BindingExpression:路径= HorizontalContentAlignment; 的DataItem = NULL; 目标元素是 'ListBoxItem的'(名称= ''); 目标属性是“HorizontalContentAlignment”(类型“的HorizontalAlignment”)
发生这种情况而做这样的绑定:
<ListBox ItemsSource="{Binding Path=MyListProperty}" />
我的数据上下文对象的这个属性:
public IList<ListBoxItem> MyListProperty{ get; set;}
一些尝试后,我发现该错误只触发时的项目数超过了我的ListBox的可见高度(例如,当垂直滚动条出现)。 于是我立即想到了虚拟化,并试图这样的:
<ListBox ItemsSource="{Binding Path=MyListProperty}" VirtualizingStackPanel.IsVirtualizing="False" />
这解决了这个问题对我来说。 虽然我宁愿保持虚拟化开启我没有使用任何更多的时间去钻研它。 我的应用程序是在复杂的一面与电网mulitiple水平,码头围板等和一些非同步的方法调用了一下。 我没能重现一个简单的应用问题。
Answer 7:
另一种解决方法/解决方案,为我工作是为了抑制这些错误(实际上,它似乎更适合叫他们警告),通过设置数据绑定源开关级类或顶层窗口的构造函数中的关键 -
#if DEBUG
System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level =
System.Diagnostics.SourceLevels.Critical;
#endif
参考: 如何抑制System.Windows.Data错误警告信息
Answer 8:
根据该数据模板化概述 MSDN上, DataTemplates
应该被用作ItemTemplate
定义数据的显示方式,而Style
将被用作ItemContainerStyle
样式刚刚产生的容器,如ListBoxItem
。
然而,似乎您试图使用后者做了前者的工作。 我无法重新创建你的情况没有太多的代码,但我怀疑的是,在集装箱式的数据绑定做可能是在假设视觉/逻辑树扔扳手。
我也不禁想到,基于项目的信息项的自定义布局要求创建自定义Panel
。 这可能是自定义更好的Panel
布局的项目比对项目给自己制定出与一个鲁贝戈德堡品种IValueConverters
。
Answer 9:
如果你想完全取代ListBoxItem
的模板,使得没有选择可见的(也许你想要的外观ItemsControl
用的分组/等行为ListBox
),那么你可以使用这个风格:
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="2" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
HorizontalAlignment="Stretch"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这个模板还排除了标准Border
包装。 如果你需要,你可以用这个代替模板:
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
如果你并不需要所有这些TemplateBinding
值,那么你可以删除一些性能。
Answer 10:
这为我工作。 在Application.xaml文件中把这个。
<Application.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</Application.Resources>
从...
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/42cd1554-de7a
Answer 11:
简单地创建类型为“ComboBoxItem”不起作用默认样式,因为它通过组合框的默认“ItemContainerStyle”覆盖。 要真正摆脱这一点,你需要更改组合框的默认“ItemContainerStyle”,就像这样:
<Style TargetType="ComboBox">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</Setter.Value>
</Setter>
</Style>
Answer 12:
我开始运行到这个问题,即使我的列表框既具有风格和ItemContainerStyle集 - 而这些命名样式已经确定HorizontalContentAlignment。 我使用CheckBox控件来开启/关闭实时过滤在我的列表框,这似乎是导致项目而不是拉从默认的样式,而不是我分配的样式。 大多数错误会发生在第一时间实时过滤踢,但此后将继续扔在每一个变化2个错误。 我觉得有趣的是在我的收藏正好2个纪录是空的,所以没有什么在项目中显示。 因此,这似乎已经contibuted。 我打算创建默认的数据显示,当一个记录是空的。
卡特的建议为我工作。 添加无键和定义的HorizontalContentAlignment物业解决问题的TargetType =“ListBoxItem的”独立的“默认”的风格。 我甚至没有需要设置OverridesDefaultStyle属性吧。
文章来源: ListBox with Grid as ItemsPanelTemplate produces weird binding errors