Цвет неактивного выделения WPF ListView

Я создаю приложение WPF, в котором несколько элементов ListView выбираются подряд (аналогично браузеру iTunes). Проблема в том, что цвет неактивного выделения по умолчанию слишком светлый. (см. ниже) Цвет неактивного выделения WPF ListView

Как я могу изменить этот цвет, чтобы мой неактивный список выглядел так? (см. ниже) Цвет неактивного выделения WPF ListView

Решение

Замените SystemColor по умолчанию на Style следующим образом:

<Style TargetType = "ListViewItem">
    <Style.Resources>
        <SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}" Color = "{x:Static SystemColors.HighlightColor}"/>
    </Style.Resources>
</Style>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
66
0
41 414
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

В шаблоне ListBox используется системный цвет под названием ControlBrush для установки неактивного цвета выделения. Следовательно, вы можете просто переопределить этот цвет:

<ListBox>
    <ListBox.Resources>
        <SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}">Red</SolidColorBrush>
    </ListBox.Resources>
</ListBox>

Есть проблемы с тем, чтобы сделать это таким образом. Это не позволяет вам изменять внешний вид приложения, и если вы измените системные цвета, изменив свою тему Windows, оно вернется обратно.

Micah 19.12.2008 23:45

Не позволяет скинуть приложение? Как так? Просто найдите ресурс по цвету, а не жестко кодируйте его как красный. Я только что протестировал изменение темы с помощью тестовой программы, и она отлично сработала. Просьба уточнить.

Kent Boogaart 19.12.2008 23:52

Это удивительно. Что произойдет, если вы поместите в форму другие списки, которые вы не хотите оформлять таким образом?

Micah 20.12.2008 00:29

Ресурс определяется на уровне ListBox, поэтому он влияет только на этот ListBox.

Kent Boogaart 20.12.2008 00:37

На самом деле происходит переопределение ключа стиля для всех объектов, которые его используют.

Micah 20.12.2008 00:39

Это ресурс, на который распространяются обычные правила поиска ресурсов. Мика, попробуй сам. Поместите два ListBoxes в Window - один с переопределением ресурса, а другой без. Изменение цвета влияет только на тот, у которого есть переопределение ресурса.

Kent Boogaart 20.12.2008 01:27

Спасибо за комментарии вам обоим. Я согласен с тем, что есть потенциальные проблемы с этим решением (переменные темы Windows и т. д.), Но в этом случае я хочу, чтобы неактивное выделение было того же цвета, что и активное выделение, поэтому это решение - именно то, что я ищу.

Joseph Sturtevant 20.12.2008 02:54

У меня точно такая же проблема. Но цвет моего шрифта должен быть белым. На данный момент он установлен на белый цвет, но этот ресурс заменяет его на черный. Есть идеи, как это изменить? Спасибо.

Daniil Harik 27.04.2009 15:05

Для .NET 4.5 похоже, что они изменили ключ - см. Ответ @ user672951 ниже.

Ed Bayiates 22.06.2013 01:01

Это ПЛОХАЯ идея - НЕ ДЕЛАЙТЕ ЭТО - для пользователей с отключенными визуальными эффектами это может испортить много вещей - полосы прокрутки и кнопки изменятся, чтобы стать текущим цветом выделения (по умолчанию это синий - так что ваши внутренние кнопки и полосы прокрутки ListView станут синими, очень плохо!). [Чтобы понять, что я имею в виду, попробуйте этот хакер по теме "Windows Classic", поскольку в ней отключены все визуальные эффекты.] Пожалуйста, прочтите популярный ответ здесь, чтобы узнать ПРАВИЛЬНЫЙ способ сделать это: stackoverflow.com/questions/1462232/…

BrainSlugs83 28.08.2014 08:31

В некоторых случаях ответ решит проблему, но он не идеален, поскольку он ломается, когда элемент управления отключен / доступен только для чтения, а также отменяет цветовые схемы, а не использует их. Я предлагаю вместо этого добавить в теги ListBox следующее:

<ListBox....>
    <ListBox.Resources>
            <Style TargetType = "ListBoxItem">
                <Setter Property = "Template">
                    <Setter.Value>
                        <ControlTemplate TargetType = "ListBoxItem">
                            <Border Name = "Border" Padding = "2" SnapsToDevicePixels = "true">
                                <ContentPresenter />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property = "IsSelected" Value = "true">
                                    <Setter TargetName = "Border" Property = "Background"
                                            Value = "{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
        </Style>
    </ListBox.Resources>
</ListBox>

Что это будет делать, так это установить цвет фона Highlight в элементе списка всякий раз, когда он выбран (независимо от состояния элемента управления).

Мой ответ основан на помощи из уже данного ответа, а также на следующем блоге: http://blogs.vbcity.com/xtab/archive/2009/06/29/9344.aspx

Это достигает того, о чем просил OP, однако обратите внимание, что этот стиль делает весь текст черным (в моей системе выделенный текст обычно белый, потому что черный на темно-синем слишком нечитаем).

Roman Starkov 12.03.2012 21:59

@romkyns просто создает обычный триггер, который устанавливает передний план на «HighlightTextBrushKey», когда IsSelected имеет значение true. Я отправлю редактирование ответа, но оно устранит указанную вами проблему. Это правильный способ делать то, что хочет OP (словарные подходы вызывают нежелательные визуальные побочные эффекты для некоторых пользователей в зависимости от их тем) ...

BrainSlugs83 28.08.2014 08:44

Довольно полезно ... Мне больше нравится этот метод, потому что цвета не перекрывают другие цвета, и он работает, пока элемент управления отключен, что было моим вариантом использования. Спасибо!

Mark W 03.06.2015 23:26

Это работает для WPF в .Net 4.6. Вы не можете создать стиль для ListBoxItem, который напрямую переопределяет Background через триггер IsSelected (это работает для многих свойств, но не для фона). Я предполагаю, что это проблема с порядком выполнения разных триггеров. Вам действительно нужно переопределить шаблон управления.

Patrick Stalph 11.07.2017 12:03

Смена SystemColors.ControlBrushKey у меня не вышла, пришлось менять SystemColors.InactiveSelectionHighlightBrushKey

Так что вместо:

<SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}" Color = "Red" />

Пришлось использовать:

<SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color = "Red"/>

Мне также пришлось изменить это значение, ControlBrushKey не менял цвет. Однако к цвету, который я ввожу, по-прежнему применяется другой цвет, поэтому мой синий выглядит более фиолетовым. Это случилось с тобой?

Caleb S 06.03.2013 05:19

Хотел бы я проголосовать за этот ответ более одного раза, так как я пытался решить эту проблему несколько раз. Я также использую .NET 4.5 и безуспешно пробовал все остальные ответы.

Zev Spitz 08.05.2013 18:45

Это то, что я использовал до того, как мне пришлось работать над проектом .NET 4 ... Мне пришлось реализовать стиль, аналогичный ответу решения для .NET 4 для моего DataGridRow, чтобы было легче работать с данными (легко зная что было выбрано).

B.K. 31.12.2013 06:05

в .net 4.5 Поле FrameworkCompatibilityPreferences.AreInactiveSelectionHighli‌ ghtBrushKeysSupporte‌ d определяет, какой цвет используется для выделения.

John Melville 09.01.2014 08:36

Вы должны переопределить некоторые свойства SystemColors. Взгляните на Класс SystemColors (MSDN). Есть больше свойств, чем InactiveSelectionHighlightBrushKey, например InactiveSelectionHighlightTextBrushKey, который влияет на цвет текста.

<Window x:Class = "WpfApplication1.MainWindow"
        xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
        Title = "MainWindow" Height = "350" Width = "525">
    <Window.Resources>
        <SolidColorBrush x:Key = "{x:Static SystemColors.HighlightBrushKey}" Color = "Red"/>
        <SolidColorBrush x:Key = "{x:Static SystemColors.HighlightTextBrushKey}" Color = "White"/>
        <SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color = "Yellow"/>
        <SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color = "Blue"/>
        <Style TargetType = "ListViewItem">
            <Setter Property = "FontSize" Value = "20" />
            <Setter Property = "FontWeight" Value = "Bold" />
            <Setter Property = "Padding" Value = "25,5" />
        </Style>
    </Window.Resources>
    <StackPanel Orientation = "Horizontal">
        <ListView>
            <ListViewItem Content = "Item" />
            <ListViewItem Content = "Item" />
        </ListView>
        <ListView>
            <ListViewItem Content = "Item" />
            <ListViewItem Content = "Item" />
        </ListView>
    </StackPanel>
</Window>

Для меня это сработало:

 <ListBox HorizontalContentAlignment = "Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Label  Margin = "-5, -2,-5,-2" Content = "{Binding Item}">
                            <Label.Style>
                                <Style TargetType = "Label">
                                    <Style.Triggers>
                                        <MultiDataTrigger>
                                            <MultiDataTrigger.Conditions>
                                                <Condition Binding = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ListBox}},Path=IsFocused}" Value = "False"/>
                                                <Condition Binding = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ListBoxItem}},Path=IsSelected}" Value = "True"/>
                                            </MultiDataTrigger.Conditions>
                                            <Setter Property = "Background" Value = "CornflowerBlue"/>
                                        </MultiDataTrigger>
                                        <DataTrigger Binding = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ListBoxItem}},Path=IsSelected}" Value = "True">
                                            <Setter Property = "Foreground" Value = "White"/>
                                        </DataTrigger>
                                        <DataTrigger Binding = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ListBoxItem}},Path=IsSelected}" Value = "False">
                                            <Setter Property = "Foreground" Value = "Black"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Label.Style>
                        </Label>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

В старых версиях .NET Framework переопределение системных цветов не работает. Решение, которое работает в .NET Framework 4.0, - здесь.

<ListView>
<ListView.Resources>
<Style TargetType = "{x:Type ListViewItem}">
    <Setter Property = "Template">
        <Setter.Value>
            <ControlTemplate TargetType = "{x:Type ListViewItem}">
                <Border x:Name = "Bd"
                        BorderBrush = "{TemplateBinding BorderBrush}"
                        BorderThickness = "{TemplateBinding BorderThickness}"
                        Background = "{TemplateBinding Background}"
                        Padding = "{TemplateBinding Padding}"
                        SnapsToDevicePixels = "true">
                    <ContentPresenter HorizontalAlignment = "{TemplateBinding HorizontalContentAlignment}"
                                        SnapsToDevicePixels = "{TemplateBinding SnapsToDevicePixels}"
                                        VerticalAlignment = "{TemplateBinding VerticalContentAlignment}" />
                </Border>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property = "Selector.IsSelectionActive"
                                        Value = "False" />
                            <Condition Property = "IsSelected"
                                        Value = "True" />
                        </MultiTrigger.Conditions>
                        <Setter Property = "Background"
                                TargetName = "Bd"
                                Value = "DarkOrange" />
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property = "Selector.IsSelectionActive"
                                        Value = "True" />
                            <Condition Property = "IsSelected"
                                        Value = "True" />
                        </MultiTrigger.Conditions>
                        <Setter Property = "Background"
                                TargetName = "Bd"
                                Value = "OrangeRed" />
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Работает как для ListBox, так и для ListView.

Хотя это может быть ценным советом для решения проблемы, хороший ответ также демонстрирует решение. Пожалуйста, РЕДАКТИРОВАТЬ, чтобы предоставить пример кода, чтобы показать, что вы имеете в виду. В качестве альтернативы, вы можете написать это как комментарий.

ρяσѕρєя K 16.01.2017 12:21

На основе этот другой ответ я использовал следующее, чтобы сделать активные и неактивные цвета одинаковыми без жесткого кодирования фактического значения:

<ListBox.Resources>
    <SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
                     Color = "{x:Static SystemColors.HighlightColor}"/>
    <SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}"
                     Color = "{x:Static SystemColors.HighlightTextColor}"/>
</ListBox.Resources>

Одни и те же цвета для активного и неактивного может не быть идеальный, но цвета по умолчанию были настолько тусклыми, что было трудно сказать, какой элемент был выбран, когда он был неактивен; это явное улучшение.

Другие вопросы по теме