我可以在<ListBox.Resources>
或<ListBox.ItemContainerStyle>
中放置一个用于ListBoxItem
的xaml Style
。请参阅代码。
问题是:有什么区别,我应该更喜欢什么?
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Top" Value="{Binding Top}"/>
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.Resources>
或:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Top" Value="{Binding Top}"/>
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
有一个答案我接受,但看看并思考这个奇怪的症状:
无论哪种方式都会给我这个奇怪的数据绑定警告:找不到引用"RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1'"的绑定源。绑定表达式:路径=水平内容对齐;数据项=空....等。
这是一个隐藏在系统 Aero 样式中某处的绑定,它不是我的。
只有当我同时使用这两种样式时,此警告才会消失!
ItemContainerStyle
是执行此操作的正确方法,因为它显式设置,因此WPF不需要始终查找样式可能的位置。它更快更好。这就是为什么该属性存在的原因。
如果未设置ItemContainerStyle
,WPF 将在 ListBox.Resources
或 Window.Resources
或 Application.Resources
中查找样式。这对性能不利。
第一个是default Style
,第二个是Explicit style
。
第一个将应用于父列表框的可视化树下的所有ListBoxItems
。
<ListBox>
<ListBox.Resources>
<!-- default Style -->
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<ListBox>
<ListBoxItem/> <-- Will be applied to this as well.
</ListBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
而第二个将仅应用于对应于外部列表框的ListBoxItems
。
第二个相当于:
<Grid>
<Grid.Resources>
<Style x:Key="MyStyle" TargetType="ListBoxItem"/>
</Grid.Resources>
<ListBox ItemContainerStyle="{StaticResource MyStyle}"/>
</Grid>
如果您查看通过 ILSpy 在 PresentationFramework.Aero.dll
下声明的默认样式,您可以在那里看到这两个 setter:
<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}}}"/>
因此,当您在资源下声明的默认样式中设置它时,它会覆盖这些资源库,因此错误消失。
但是,如果您将其设置为内联声明的样式ItemContainerStyle
则该错误不会消失,因为它仍然引用默认样式。如果您不想基于默认样式BasedOn
属性设置为 x:Null
.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{x:Null}"/>
</ListBox.ItemContainerStyle>
</ListBox>