Overriding SystemColors in local Resources dictionary

半世苍凉 提交于 2019-12-22 01:36:19

问题


I'm trying to hide the visual hints that indicate selection in a WPF ListBox. This answer suggests this should work by overriding the SystemColors for that ListBox.

I created a new WPF project and edited the MainWindow.xaml like this:

<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>

Unfortunately this doesn't work, the window appears like this:

Any idea what I'm doing wrong? How can I remove the blue colors that appear on the selected item and on the one hovered?


回答1:


definitely it wont work. Since ListBox.Resources will set a resource for ListBox not for ListBoxItem. So here is a solution:

<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>

Attach this style in windows.resource like:

<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>

And defiantly you can put more SolidColorBrush into Style.Resources like what you did in your code.




回答2:


the only way I have found to override this default behavior is to override the default style for ListBoxItem. I extract the default style from blend and override it for your needs. Here is how it's done in my case:

<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>

And you can still select the items:

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

    var selectedItem = listBox.SelectedItem;
}

Hope this helps.




回答3:


If you wish to disable the highlighting when a listboxitem is selected or mouse over, you can use the below code.

<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}"/>


来源:https://stackoverflow.com/questions/38042016/overriding-systemcolors-in-local-resources-dictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!