【问题标题】:WPF. ListBox item styleWPF。列表框项样式
【发布时间】:2015-07-17 07:02:38
【问题描述】:

我的 ListBox 项目样式有问题,我创建了两种样式但不知道如何一起使用。第一种样式用于 ListBox 项目大小、鼠标悬停颜色等,或者第二种用于项目背景(交替计数)。如果我离开其中一个,它们可以正常工作,但是如何使它们一起工作?或者也许我可以用一种风格来写?

我的代码是:

..... <Style x:Key="Style2"
       TargetType="{x:Type ListBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border 
                        Name="Border"
                        Padding="7"
                        SnapsToDevicePixels="True">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background"
                                    Value="{StaticResource SelectedBackgroundBrush}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground"
                                    Value="{StaticResource DisabledForegroundBrush}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#FFFFFF"></Setter>
            </Trigger>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="#F7F7F7"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style  x:Key="{x:Type ListBoxItem}"
        TargetType="{x:Type ListBoxItem}"
        BasedOn="{StaticResource Style2}">
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#19f39611"></Setter>
            </Trigger>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="#19000000"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>


<Grid >
    <ScrollViewer Margin="30,98,362,30">
        <ListBox x:Name="lbPersonList" AlternationCount="2">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>
</Grid>

【问题讨论】:

    标签: wpf xaml styles listboxitem


    【解决方案1】:

    您可以使用BasedOn

    <Style x:Key="Style1" TargetType="ListBoxItem">
        ...
    </Style>
    
    <Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem" BasedOn={StaticResource Style1}>
        ...
    </Style>
    

    已编辑

    问题出在 ControlTemplate 的背景设置器上。这是解决方案(使用 AlternationConverter 而不是触发器):

    <Window.Resources>
        <AlternationConverter x:Key="BackgroundConverter">
            <SolidColorBrush Color="#19f39611" />
            <SolidColorBrush Color="#19000000" />
        </AlternationConverter>
    
        <Style x:Key="Style2" TargetType="{x:Type ListBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="Border" Padding="7" SnapsToDevicePixels="True" Background="{TemplateBinding Background}">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="Border" Property="Background" Value="Gray"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="Green"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <Style x:Key="Style1" TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource Style2}">
            <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},
                     Path=(ItemsControl.AlternationIndex),
                     Converter={StaticResource BackgroundConverter}}"/>
        </Style>
    </Window.Resources>
    
    <ListBox x:Name="lbPersonList" AlternationCount="2" ItemContainerStyle="{StaticResource Style1}">
    ...
    

    【讨论】:

    • 如果我使用您的示例我如何在 ListBox 选项中调用此样式?因为知道它的唯一工作方式1(Alternationcount 不工作)
    • 问题出在 ControlTemplate 的背景设置器上。我编辑了我的答案。
    【解决方案2】:

    使用Dynamic resource,您可以使用单个列表框样式实现此目的

     <Window.Resources>                              
        <Style x:Key="Lststyle" TargetType="ListBoxItem">           
            <Setter Property="SnapsToDevicePixels" Value="true"/>        
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="Border" Background="Transparent" Padding="7" SnapsToDevicePixels="True">                         
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="ListBox.AlternationIndex" Value="0">
                                <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color0}"/>
                            </Trigger>
                            <Trigger Property="ListBox.AlternationIndex" Value="1">
                                <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color1}"/>
                            </Trigger>
                            <Trigger Property="ListBoxItem.IsSelected" Value="true">
                                <Setter TargetName="Border" Property="Background" Value="Green"/>
                            </Trigger>
                            <Trigger Property="ListBoxItem.IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="LightGray"/>
                            </Trigger>                           
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>          
        </Style>   
    </Window.Resources>
    
    <StackPanel >
        <TextBlock Text="Listbox1"></TextBlock>
        <ScrollViewer >
            <ListBox x:Name="lbPersonList" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2"> 
                <ListBox.Resources>
                    <SolidColorBrush x:Key="Color0" Color="#19f39611"></SolidColorBrush>
                    <SolidColorBrush x:Key="Color1" Color="#19000000"></SolidColorBrush>
                </ListBox.Resources>
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock  Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
            </ListBox>
        </ScrollViewer>
        <TextBlock Margin="0,10,0,0" Text="Listbox2"></TextBlock>
        <ScrollViewer>
            <ListBox x:Name="lbPersonList1" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">
                <ListBox.Resources>
                    <SolidColorBrush x:Key="Color0" Color="Yellow"></SolidColorBrush>
                    <SolidColorBrush x:Key="Color1" Color="Blue"></SolidColorBrush>
                </ListBox.Resources>
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
            </ListBox>
        </ScrollViewer>
    </StackPanel>
    

    简化的 xaml

    <Window.Resources>
        <Style x:Key="lst1" TargetType="ListBox" >
            <Style.Resources>
                <SolidColorBrush x:Key="Color0" Color="#19f39611"></SolidColorBrush>
                <SolidColorBrush x:Key="Color1" Color="#19000000"></SolidColorBrush>
            </Style.Resources>
        </Style>
        <Style x:Key="lst2" TargetType="ListBox" >
            <Style.Resources>
                <SolidColorBrush x:Key="Color0" Color="Blue"></SolidColorBrush>
                <SolidColorBrush x:Key="Color1" Color="Yellow"></SolidColorBrush>
            </Style.Resources>
        </Style>
        <Style x:Key="Lststyle" TargetType="ListBoxItem">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="Border" Background="Transparent" Padding="7" SnapsToDevicePixels="True">
                            <Border.Style>
                                <Style TargetType="Border">
                                    <Style.Triggers>
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                                            <Setter  Property="Background" Value="{DynamicResource Color0}"/>
                                        </Trigger>
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                            <Setter  Property="Background" Value="{DynamicResource Color1}"/>
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </Border.Style>
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="ListBox.AlternationIndex" Value="0">
                                <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color0}"/>
                            </Trigger>
                            <Trigger Property="ListBox.AlternationIndex" Value="1">
                                <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color1}"/>
                            </Trigger>
                            <Trigger Property="ListBoxItem.IsSelected" Value="true">
                                <Setter TargetName="Border" Property="Background" Value="Green"/>
                            </Trigger>
                            <Trigger Property="ListBoxItem.IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="LightGray"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
    </Window.Resources>
    <StackPanel >
        <TextBlock Text="Listbox1"></TextBlock>
        <ScrollViewer >
            <ListBox x:Name="lbPersonList" Style="{StaticResource lst1}" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">![enter image description here][2]              
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock  Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
            </ListBox>
        </ScrollViewer>
        <TextBlock Margin="0,10,0,0" Text="Listbox2"></TextBlock>
        <ScrollViewer>
            <ListBox x:Name="lbPersonList1" Style="{StaticResource lst2}" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">               
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
                <TextBlock Text="listboxitem1"></TextBlock>
            </ListBox>
        </ScrollViewer>
    </StackPanel>
    

    【讨论】:

      【解决方案3】:

      您应该为每种样式设置一个正确的x:Key,然后您可以使用BasedOn={StaticResource Style1} 附加到您当前的样式样式1 中。 (查看文档:https://msdn.microsoft.com/en-us/library/system.windows.style.basedon(v=vs.110).aspx

      检查这个:

          <Style x:Key="Style2"
                 TargetType="ListBoxItem">
              <Style.Triggers>
                  <Trigger Property="ItemsControl.AlternationIndex"
                           Value="0">
                      <Setter Property="Background"
                              Value="#19f39611"></Setter>
                  </Trigger>
                  <Trigger Property="ItemsControl.AlternationIndex"
                           Value="1">
                      <Setter Property="Background"
                              Value="#19000000"></Setter>
                  </Trigger>
              </Style.Triggers>
              <Setter Property="Template">
                  <Setter.Value>
                      <ControlTemplate TargetType="ListBoxItem">
                          <Border Name="Border"
                                  Padding="7"
                                  SnapsToDevicePixels="True">
                              <ContentPresenter />
                          </Border>
                          <ControlTemplate.Triggers>
                              <Trigger Property="IsSelected"
                                       Value="true">
                                  <Setter Property="Background"
                                          Value="Red" />
                              </Trigger>
                              <Trigger Property="IsEnabled"
                                       Value="false">
                                  <Setter Property="Foreground"
                                          Value="Gray" />
                              </Trigger>
                          </ControlTemplate.Triggers>
                      </ControlTemplate>
                  </Setter.Value>
              </Setter>
          </Style>
      
          <Style  TargetType="{x:Type ListBoxItem}"
                  BasedOn="{StaticResource Style2}">
              <Setter Property="SnapsToDevicePixels"
                      Value="true" />
              <Style.Triggers>
      
                  <Trigger Property="ListBox.AlternationIndex"
                           Value="0">
                      <Setter Property="Background"
                              Value="CornflowerBlue" />
                      <Setter Property="Foreground"
                              Value="Black" />
                  </Trigger>
      
                  <Trigger Property="ItemsControl.AlternationIndex"
                           Value="1">
                      <Setter Property="Background"
                              Value="LightBlue" />
                      <Setter Property="Foreground"
                              Value="Red" />
                  </Trigger>
              </Style.Triggers>
          </Style>
      

      【讨论】:

      • 好的,我修复了它,以及我必须如何在 ListBox 选项中编写它(参见 .....)?因为现在只有第一种风格的作品(交替计数不起作用)
      • 检查新的更新。:D 好吧,你必须知道,使用BasedOn,新样式将覆盖所有已经定义的样式。例如Alternation 不能同时工作。它将只考虑其中的一种,因为该触发器在两种样式中都定义了。
      • 我怎样才能让它们一起工作?也许它可能的交替计数属性放在第一个样式中?
      • 嗯...我真的不明白你想如何组合它们。有它依赖的属性吗?至少,要么有(例如蓝色和红色),要么是其他的。你能详细解释一下这个场景吗?所以正如我所说,如果它在两种样式中定义,则不能组合。一次应该有1个触发器应用于Alternation(不能是两个,三个等等)。
      • 也许你知道如何在没有触发器的情况下进行交替?
      猜你喜欢
      • 1970-01-01
      • 2012-06-25
      • 2010-09-26
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多