<ListBox.Resources> 或 <ListBox.ItemContainerStyle> 中的 ListBoxItem 样式?



我可以在<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.ResourcesWindow.ResourcesApplication.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>

相关内容

  • 没有找到相关文章

最新更新