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

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

Замените SystemColor по умолчанию на Style следующим образом:
<Style TargetType = "ListViewItem">
<Style.Resources>
<SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}" Color = "{x:Static SystemColors.HighlightColor}"/>
</Style.Resources>
</Style>





В шаблоне ListBox используется системный цвет под названием ControlBrush для установки неактивного цвета выделения. Следовательно, вы можете просто переопределить этот цвет:
<ListBox>
<ListBox.Resources>
<SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}">Red</SolidColorBrush>
</ListBox.Resources>
</ListBox>
Не позволяет скинуть приложение? Как так? Просто найдите ресурс по цвету, а не жестко кодируйте его как красный. Я только что протестировал изменение темы с помощью тестовой программы, и она отлично сработала. Просьба уточнить.
Это удивительно. Что произойдет, если вы поместите в форму другие списки, которые вы не хотите оформлять таким образом?
Ресурс определяется на уровне ListBox, поэтому он влияет только на этот ListBox.
На самом деле происходит переопределение ключа стиля для всех объектов, которые его используют.
Это ресурс, на который распространяются обычные правила поиска ресурсов. Мика, попробуй сам. Поместите два ListBoxes в Window - один с переопределением ресурса, а другой без. Изменение цвета влияет только на тот, у которого есть переопределение ресурса.
Спасибо за комментарии вам обоим. Я согласен с тем, что есть потенциальные проблемы с этим решением (переменные темы Windows и т. д.), Но в этом случае я хочу, чтобы неактивное выделение было того же цвета, что и активное выделение, поэтому это решение - именно то, что я ищу.
У меня точно такая же проблема. Но цвет моего шрифта должен быть белым. На данный момент он установлен на белый цвет, но этот ресурс заменяет его на черный. Есть идеи, как это изменить? Спасибо.
Для .NET 4.5 похоже, что они изменили ключ - см. Ответ @ user672951 ниже.
Это ПЛОХАЯ идея - НЕ ДЕЛАЙТЕ ЭТО - для пользователей с отключенными визуальными эффектами это может испортить много вещей - полосы прокрутки и кнопки изменятся, чтобы стать текущим цветом выделения (по умолчанию это синий - так что ваши внутренние кнопки и полосы прокрутки ListView станут синими, очень плохо!). [Чтобы понять, что я имею в виду, попробуйте этот хакер по теме "Windows Classic", поскольку в ней отключены все визуальные эффекты.] Пожалуйста, прочтите популярный ответ здесь, чтобы узнать ПРАВИЛЬНЫЙ способ сделать это: stackoverflow.com/questions/1462232/…
В некоторых случаях ответ решит проблему, но он не идеален, поскольку он ломается, когда элемент управления отключен / доступен только для чтения, а также отменяет цветовые схемы, а не использует их. Я предлагаю вместо этого добавить в теги 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, однако обратите внимание, что этот стиль делает весь текст черным (в моей системе выделенный текст обычно белый, потому что черный на темно-синем слишком нечитаем).
@romkyns просто создает обычный триггер, который устанавливает передний план на «HighlightTextBrushKey», когда IsSelected имеет значение true. Я отправлю редактирование ответа, но оно устранит указанную вами проблему. Это правильный способ делать то, что хочет OP (словарные подходы вызывают нежелательные визуальные побочные эффекты для некоторых пользователей в зависимости от их тем) ...
Довольно полезно ... Мне больше нравится этот метод, потому что цвета не перекрывают другие цвета, и он работает, пока элемент управления отключен, что было моим вариантом использования. Спасибо!
Это работает для WPF в .Net 4.6. Вы не можете создать стиль для ListBoxItem, который напрямую переопределяет Background через триггер IsSelected (это работает для многих свойств, но не для фона). Я предполагаю, что это проблема с порядком выполнения разных триггеров. Вам действительно нужно переопределить шаблон управления.
Смена SystemColors.ControlBrushKey у меня не вышла, пришлось менять
SystemColors.InactiveSelectionHighlightBrushKey
Так что вместо:
<SolidColorBrush x:Key = "{x:Static SystemColors.ControlBrushKey}" Color = "Red" />
Пришлось использовать:
<SolidColorBrush x:Key = "{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color = "Red"/>
Мне также пришлось изменить это значение, ControlBrushKey не менял цвет. Однако к цвету, который я ввожу, по-прежнему применяется другой цвет, поэтому мой синий выглядит более фиолетовым. Это случилось с тобой?
Хотел бы я проголосовать за этот ответ более одного раза, так как я пытался решить эту проблему несколько раз. Я также использую .NET 4.5 и безуспешно пробовал все остальные ответы.
Это то, что я использовал до того, как мне пришлось работать над проектом .NET 4 ... Мне пришлось реализовать стиль, аналогичный ответу решения для .NET 4 для моего DataGridRow, чтобы было легче работать с данными (легко зная что было выбрано).
в .net 4.5 Поле FrameworkCompatibilityPreferences.AreInactiveSelectionHighli ghtBrushKeysSupporte d определяет, какой цвет используется для выделения.
Вы должны переопределить некоторые свойства 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.
Хотя это может быть ценным советом для решения проблемы, хороший ответ также демонстрирует решение. Пожалуйста, РЕДАКТИРОВАТЬ, чтобы предоставить пример кода, чтобы показать, что вы имеете в виду. В качестве альтернативы, вы можете написать это как комментарий.
На основе этот другой ответ я использовал следующее, чтобы сделать активные и неактивные цвета одинаковыми без жесткого кодирования фактического значения:
<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>
Одни и те же цвета для активного и неактивного может не быть идеальный, но цвета по умолчанию были настолько тусклыми, что было трудно сказать, какой элемент был выбран, когда он был неактивен; это явное улучшение.
Есть проблемы с тем, чтобы сделать это таким образом. Это не позволяет вам изменять внешний вид приложения, и если вы измените системные цвета, изменив свою тему Windows, оно вернется обратно.