【问题标题】:Setting Background Color or WPF (4.0) ListBox - Windows 8设置背景颜色或 WPF (4.0) 列表框 - Windows 8
【发布时间】:2013-05-25 01:10:51
【问题描述】:

我正在尝试将所选 ListBoxItem 的背景颜色设置为白色,而不是系统颜色。我已经阅读了我可以在 SO 上找到的内容,并且已经遵循或相信已经遵循了那里的建议(Change background color for selected ListBox itemWPF How to change the listbox selected item text color when the list box loses focusChange selected and unfocused Listbox style to not be grayed out 等)。

所有似乎都通过将选定项目的 HighlightBrush 和 ControlBrush 设置为透明来解决问题。我有以下 XAML,它正确设置了字体颜色,但无论画笔设置如何,背景都是默认的透明蓝色。我还是一个 WPF 菜鸟,所以我一定在这里遗漏了一些简单的东西。

<ListBox Width="Auto" Height="Auto" Grid.Column="0" BorderThickness="0" Background="#FFF3F3F3" xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <ListBox.ItemsSource>
       <x:Array Type="{x:Type sys:String}">
          <sys:String>String 1</sys:String>
          <sys:String>String 2</sys:String>
          <sys:String>String 3</sys:String>
          <sys:String>String 4</sys:String>
       </x:Array>
    </ListBox.ItemsSource>
    <ListBox.ItemContainerStyle>
       <Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
          <Style.Resources>
             <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
             <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
          </Style.Resources>
          <Setter Property="HorizontalContentAlignment" Value="Stretch" />
          <Setter Property="FontSize" Value="16"/>
          <Setter Property="Foreground" Value="#999999"/>
          <Style.Triggers>
             <Trigger Property="IsSelected" Value="True" >
                <Setter Property="Background" Value="White" />
                <Setter Property="Foreground" Value="Black" />
             </Trigger>
          </Style.Triggers>
       </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
       <DataTemplate>
          <TextBlock Text="{Binding}" HorizontalAlignment="Right" Margin="0,0,8,0" Background="Transparent"/>
       </DataTemplate>
    </ListBox.ItemTemplate>
 </ListBox>

我会很感激任何朝着正确方向的推动。

编辑

在阅读了第一个对他们有用的答案并稍作改动后,我使用了我一直在 Windows 8 机器上开发的应用程序,并在 Windows 7 VM 中执行它,它按预期工作。关于需要更改哪些内容才能使其在 Windows 8 机器和 Windows 7 上运行的任何想法?

【问题讨论】:

    标签: c# wpf windows-8


    【解决方案1】:

    所以你只是想让所选项目的背景变白?

    您的代码减去 ControlBrushKey 设置对我有用:

    <Style.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White" />
    </Style.Resources>
    

    【讨论】:

    • 很有趣,所以在阅读完这篇文章后,我将我的应用程序带到了 Windows 7 机器上,它按预期工作。但在我的 Windows 8 机器上却没有。
    • 对,在 Windows .Net 4.5 之前的版本中效果很好但是由于深不可测的原因,触发值从系统画笔更改为具有动态资源的硬编码颜色值。因此,像这样覆盖这些资源将不再影响 ListBox。我认为其他控件的情况也类似,但到目前为止我只在 ListBox 上进行了验证。
    【解决方案2】:

    对于 Windows-8,这些帖子已经过时了。

    在 Windows-8 中,出于某种原因,Microsoft 不希望人们如此轻松地编辑他们的默认 Style 或使用 Brush 覆盖的东西。

    ListBoxItem 来自 VS 的默认 Style 用于选择触发器:

    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="Selector.IsSelectionActive"
                    Value="False" />
        <Condition Property="IsSelected"
                    Value="True" />
      </MultiTrigger.Conditions>
      <Setter TargetName="Bd"
              Property="Background"
              Value="#3DDADADA" />
      <Setter TargetName="Bd"
              Property="BorderBrush"
              Value="#FFDADADA" />
    </MultiTrigger>
    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="Selector.IsSelectionActive"
                    Value="True" />
        <Condition Property="IsSelected"
                    Value="True" />
      </MultiTrigger.Conditions>
      <Setter TargetName="Bd"
              Property="Background"
              Value="#3D26A0DA" />
      <Setter TargetName="Bd"
              Property="BorderBrush"
              Value="#FF26A0DA" />
    </MultiTrigger>
    

    选择状态的触发器不再应用我们可以轻松覆盖的画笔,而是静态颜色。因此,要修改它,您将需要派生模板并在那里修改触发器。给White

    这是 VS2012 Windows-8 为ListBoxItem 提供的完整样式

    <Style x:Key="ListBoxItemStyle1"
           TargetType="{x:Type ListBoxItem}">
      <Setter Property="SnapsToDevicePixels"
              Value="True" />
      <Setter Property="Padding"
              Value="4,1" />
      <Setter Property="HorizontalContentAlignment"
              Value="{Binding HorizontalContentAlignment,
                              RelativeSource={RelativeSource FindAncestor,
                                                             AncestorLevel=1,
                                                             AncestorType={x:Type ItemsControl}}}" />
      <Setter Property="VerticalContentAlignment"
              Value="{Binding VerticalContentAlignment,
                              RelativeSource={RelativeSource FindAncestor,
                                                             AncestorLevel=1,
                                                             AncestorType={x:Type ItemsControl}}}" />
      <Setter Property="Background"
              Value="Transparent" />
      <Setter Property="BorderBrush"
              Value="Transparent" />
      <Setter Property="BorderThickness"
              Value="1" />
      <Setter Property="FocusVisualStyle">
        <Setter.Value>
          <Style>
            <Setter Property="Control.Template">
              <Setter.Value>
                <ControlTemplate>
                  <Rectangle Margin="2"
                             SnapsToDevicePixels="True"
                             Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
                             StrokeDashArray="1 2"
                             StrokeThickness="1" />
                </ControlTemplate>
              </Setter.Value>
            </Setter>
          </Style>
        </Setter.Value>
      </Setter>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
            <Border x:Name="Bd"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}"
                    SnapsToDevicePixels="True">
              <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding Content}"
                                ContentStringFormat="{TemplateBinding ContentStringFormat}"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Border>
            <ControlTemplate.Triggers>
              <MultiTrigger>
                <MultiTrigger.Conditions>
                  <Condition Property="IsMouseOver"
                             Value="True" />
                </MultiTrigger.Conditions>
                <Setter TargetName="Bd"
                        Property="Background"
                        Value="#1F26A0DA" />
                <Setter TargetName="Bd"
                        Property="BorderBrush"
                        Value="#A826A0DA" />
              </MultiTrigger>
              <MultiTrigger>
                <MultiTrigger.Conditions>
                  <Condition Property="Selector.IsSelectionActive"
                             Value="False" />
                  <Condition Property="IsSelected"
                             Value="True" />
                </MultiTrigger.Conditions>
                <Setter TargetName="Bd"
                        Property="Background"
                        Value="#3DDADADA" />
                <Setter TargetName="Bd"
                        Property="BorderBrush"
                        Value="#FFDADADA" />
              </MultiTrigger>
              <MultiTrigger>
                <MultiTrigger.Conditions>
                  <Condition Property="Selector.IsSelectionActive"
                             Value="True" />
                  <Condition Property="IsSelected"
                             Value="True" />
                </MultiTrigger.Conditions>
                <Setter TargetName="Bd"
                        Property="Background"
                        Value="#3D26A0DA" />
                <Setter TargetName="Bd"
                        Property="BorderBrush"
                        Value="#FF26A0DA" />
              </MultiTrigger>
              <Trigger Property="IsEnabled"
                       Value="False">
                <Setter TargetName="Bd"
                        Property="TextElement.Foreground"
                        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    

    如果您将这些触发器修改为:

    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="Selector.IsSelectionActive"
                    Value="False" />
        <Condition Property="IsSelected"
                    Value="True" />
      </MultiTrigger.Conditions>
      <Setter TargetName="Bd"
              Property="Background"
              Value="White" />
      <Setter TargetName="Bd"
              Property="BorderBrush"
              Value="White" />
    </MultiTrigger>
    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="Selector.IsSelectionActive"
                    Value="True" />
        <Condition Property="IsSelected"
                    Value="True" />
      </MultiTrigger.Conditions>
      <Setter TargetName="Bd"
              Property="Background"
              Value="White" />
      <Setter TargetName="Bd"
              Property="BorderBrush"
              Value="White" />
    </MultiTrigger>
    

    你的问题应该已经解决了。

    【讨论】:

    • 非常感谢。让我做一些关于从模板派生以覆盖并确保它工作的研究,因为我相信它会,并将它标记为已回答。
    • @RobGoodwin 欢迎您。您可以从dropbox.com/s/4ni0dbcgzji5h8n/ListBoxSelectionWin8.rar 下载我为您的问题汇总的示例,以查看样式覆盖。
    • 那行得通。感谢您花时间发布样本。它使我能够在 Windows 7 和 8 上快速进行测试。它为我提供了一些当前用于学习 WPF 控件样式的资源。
    • @DefenestrationDay 不确定你的意思。答案中提到的“此方法”只是您使用自定义画笔指定的Style,而不是默认画笔。 AlternationCount 是一个属性,您仍然可以在 ListBox 上设置它,并说如果您在 &lt;ControlTemplate.Triggers&gt;&lt;ControlTemplate.Triggers&gt; 内有 &lt;Trigger Property="ListBox.AlternationIndex" Value="0"&gt;&lt;Setter Property="Foreground" Value="Tomato" /&gt;&lt;/Trigger&gt; 之类的触发器 Style 您会看到 Foreground 切换到 Tomato对于索引为 0 为 AlternationIndex 的项目就可以了。
    • 谢谢!以为我要疯了一会儿!
    【解决方案3】:

    将以下触发器添加到我的 Item DataTemplate,适用于 Windows 10:

    <DataTemplate x:Key="MyItemTemplate">
        <Border Name="Border" Background="Transparent" BorderBrush="LightGray" BorderThickness="0,1,0,0" Padding="0">
            <TextBlock Text="{Binding Text}" HorizontalAlignment="Left" FontWeight="Medium" />
        </Border>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
                <Setter TargetName="Border" Property="Background" Value="SkyBlue"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
    

    【讨论】:

    • 适用于 Windows 8 的最简洁的解决方案!
    • 我希望我能投票更多。比上面这些其他 hacky 解决方案要好得多!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2011-02-11
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多