在本地资源字典中覆盖SystemColors

5
我正在尝试隐藏WPF ListBox 中指示选择的视觉提示。 此答案 建议通过覆盖该 ListBoxSystemColors 来实现这一点。
我创建了一个新的 WPF 项目并编辑了 MainWindow.xaml,如下所示:
<Window x:Class="WpfListboxWithoutSelection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfListboxWithoutSelection"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="325">
  <Grid>
    <ListBox>
      <ListBox.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
      </ListBox.Resources>
      <s:String>Item 1</s:String>
      <s:String>Item 2</s:String>
      <s:String>Item 3</s:String>
    </ListBox>
  </Grid>
</Window>

很不幸,这并不起作用,窗口看起来像这样:

有什么想法我做错了什么?如何去除所选项目和悬停在其上的蓝色颜色?
3个回答

6

肯定行不通。因为ListBox.Resources是为ListBox设置资源,而不是为ListBoxItem设置资源。因此,这里有一个解决方案:

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent"/>
    </Style.Resources>
</Style>

在 windows.resource 中添加此样式:
<Window.Resources>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent"/>
        </Style.Resources>
    </Style>
</Window.Resources>

你可以像你在代码中所做的那样,在Style.Resources中添加更多的SolidColorBrush。


但是为什么这个其他回答有37个赞,而且每个人都说它对他们有效呢? - Jonas Sourlier
1
是的,你的解决方案也是正确的。但有时这取决于机器。即使你的解决方案在我的机器上运行良好。我想我的代码也会在你的机器上运行(看起来像是Windows 8.1或10)。 - Suman Kumar

1
我发现覆盖默认行为的唯一方法是覆盖 ListBoxItem 的默认样式。我从 Blend 中提取出默认样式,并根据您的需求进行了覆盖。以下是我个人的操作步骤:
<Window
    x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApplication2"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:s="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow"
    Width="525"
    Height="350"
    mc:Ignorable="d">

    <Window.Resources>

        <!--  This is default ListboxItemStyle  -->
        <Style x:Key="ListboxItemControlDefault" TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border
                            x:Name="Bd"
                            Padding="{TemplateBinding Padding}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            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>


        <!--  This is modified ListboxItemStyle  -->
        <Style x:Key="ListboxItemControlModified" TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border
                            x:Name="Bd"
                            Padding="{TemplateBinding Padding}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            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="Transparent" />
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False" />
                                    <Condition Property="IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Background" Value="Transparent" />
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="True" />
                                    <Condition Property="IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Background" Value="Transparent" />
                                <Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
                            </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>
    </Window.Resources>

    <Grid>
        <ListBox ItemContainerStyle="{StaticResource ListboxItemControlModified}" SelectionChanged="ListBox_SelectionChanged">
            <s:String>Item 1</s:String>
            <s:String>Item 2</s:String>
            <s:String>Item 3</s:String>
            <s:String>Item 4</s:String>
        </ListBox>
    </Grid>
</Window>

而且您仍然可以选择这些项目:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var listBox = sender as ListBox;

    var selectedItem = listBox.SelectedItem;
}

希望这有所帮助。

-1
如果您希望在选择列表框项或鼠标悬停时禁用高亮显示,可以使用以下代码。
<Style TargetType="ListBoxItem" x:Key="ListBoxItemStyle">
    <Setter Property="IsSelected" Value="{Binding Content.IsSelected, Mode=TwoWay, RelativeSource={RelativeSource Self}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<ListBox ItemContainerStyle="{StaticResource ListBoxItemStyle}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接