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

Ger*_*ard 5 wpf xaml styles listbox

我可以把一个XAML StyleListBoxItem<ListBox.Resources><ListBox.ItemContainerStyle>.见代码.
问题是:有什么区别,我更喜欢什么?

<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>
Run Code Online (Sandbox Code Playgroud)

要么:

<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>
Run Code Online (Sandbox Code Playgroud)

有一个我接受的答案,但是看到并想一想这个奇怪的症状:
无论哪种方式都给我这个奇怪的数据绑定警告:找不到用于引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel的绑定源= '1'".BindingExpression:路径= Horizo​​ntalContentAlignment; DataItem = null ....等.
这是一个隐藏在系统Aero样式某处的绑定,它不是我的.
只有当我使用这两种样式时,此警告才会消失!

dev*_*hog 10

ItemContainerStyle这是正确的方法,因为它明确设置,所以wpf不需要总是查找样式的位置.它更快更好.这就是为什么那个属性存在的原因.

如果ItemContainerStyle没有设置WPF将寻求在风格ListBox.ResourcesWindow.ResourcesApplication.Resources.这对性能不利.

  • 是的,虽然效果是以毫秒为单位,如果您有20个resourcedictionary可能会在您编写自己的主题时发生,您会注意到列表框不再滚动,因为项目被添加或删除到visualtree,每次更改时查找过程必须继续20个资源.所以最终技术上itemcontainerstyle将是最好的方式.最后两种方法都会给你一种风格.然而,如果比另一个快. (2认同)

Roh*_*ats 6

第一是default Style第二是Explicit style.

第一个将应用于ListBoxItems在父ListBox的VisualTree下找到的所有内容.

<ListBox>
  <ListBox.Resources>
    <!-- default Style -->
  </ListBox.Resources>
  <ListBox.ItemTemplate>
     <DataTemplate>
        <ListBox>
           <ListBoxItem/> <-- Will be applied to this as well.
        </ListBox>
     </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

而第二个将仅应用于ListBoxItems外部ListBox.

第二个相当于:

<Grid>
  <Grid.Resources>
     <Style x:Key="MyStyle" TargetType="ListBoxItem"/>
  </Grid.Resources>
  <ListBox ItemContainerStyle="{StaticResource MyStyle}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

如果你看看PresentationFramework.Aero.dll通过ILSpy 声明的默认样式,你可以在那里看到这两个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}}}"/>
Run Code Online (Sandbox Code Playgroud)

因此,当您在资源下声明的默认样式中设置它,它会覆盖那些setter,因此错误消失.

但是,如果您将其设置为声明内联的样式,则ItemContainerStyle该错误将不会消失,因为它仍然引用默认样式.如果您不想将basedOn默认样式集BasedOn属性设置为x:Null.

<ListBox>
   <ListBox.ItemContainerStyle>
      <Style TargetType="ListBoxItem" BasedOn="{x:Null}"/>
   </ListBox.ItemContainerStyle>
</ListBox>
Run Code Online (Sandbox Code Playgroud)