Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
 Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
На многих ресурсах для изменения цвета выделенного элемента предлагается изменить системные предопределённые цвета SystemColors.HighlightTextBrushKey, SystemColors.HighlightBrushKey, SystemColors.ControlBrushKey. Я проверял этот способ - но результат нулевой. Один из проверенных вариантов
    <Grid>
        <Grid.Resources>
            <Style x:Key="myListboxStyle">
                <Style.Resources>
                    <!-- Item TextColor -->
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#0505F3" />
                    <!-- Background of selected item when focussed -->
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00FF3D" />
                    <!-- Background of selected item when not focussed -->
                    <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#3F8257" />
                </Style.Resources>
            </Style>
        </Grid.Resources>
        <ListBox Style="{StaticResource myListboxStyle}">
            <ListBoxItem Content="Строка Один"/>
            <ListBoxItem Content="Строка Два"/>
            <ListBoxItem Content="Строка Три"/>
            <ListBoxItem Content="Строка Четыре"/>
            <ListBoxItem Content="Строка Пять"/>
        </ListBox>
    </Grid>

Кто может объяснить в чём причина? Есть какие-то особенности применения? Или этот метод когда-то работал, а сейчас перестал?

В данный момент для этого я использую определение стиля в ресурсах ListBox
            <ListBox.Resources>
                <Style TargetType="ListBoxItem">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Foreground" Value="Blue"/>
                        </Trigger> 
                    </Style.Triggers>
                </Style>
            </ListBox.Resources>
Правильный ли такой подход?
11 окт 18, 13:57    [21701592]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3167
шаблон ListBoxItem переопределен?
11 окт 18, 14:03    [21701603]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4604
Eld Hasp
Кто может объяснить в чём причина? Есть какие-то особенности применения? Или этот метод когда-то работал, а сейчас перестал?

Эти цвета и эта раскраска применяется для ListBoxItem. В другой теме уже говорилось, что ListBoxItem и ListBox - это разные визуальные дереья, и ListBoxItem не может видеть ресурсы из стиля ListBox. Эти переопределенные цвета нужно помещать в стиль ListBoxItem:
<ListBox Grid.Column="2">
  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <Style.Resources>
        <!-- Item TextColor -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#0505F3" />
        <!-- Background of selected item when focussed -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00FF3D" />
        <!-- Background of selected item when not focussed -->
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#3F8257" />
      </Style.Resources>
    </Style>
  </ListBox.ItemContainerStyle>
  <ListBoxItem Content="Строка Один"/>
  <ListBoxItem Content="Строка Два"/>
  <ListBoxItem Content="Строка Три"/>
  <ListBoxItem Content="Строка Четыре"/>
  <ListBoxItem Content="Строка Пять"/>
</ListBox>

P.S. Я бы лично не стал переопределять системные цвета - это будет влиять на всё приложение. Просто сделал бы отдельный стиль для листбокса, где в триггерах бы напрямую указал, в каком случае какой цвет, и всё.
11 окт 18, 14:37    [21701646]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны
P.S. Я бы лично не стал переопределять системные цвета - это будет влиять на всё приложение. Просто сделал бы отдельный стиль для листбокса, где в триггерах бы напрямую указал, в каком случае какой цвет, и всё.
То есть вариант с триггерами, который я привёл, это верное решение?
Roman Mejtes
шаблон ListBoxItem переопределен?
Нет, весь код указан здесь полностью.
11 окт 18, 16:04    [21701741]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны
Эти цвета и эта раскраска применяется для ListBoxItem. В другой теме уже говорилось, что ListBoxItem и ListBox - это разные визуальные дереья, и ListBoxItem не может видеть ресурсы из стиля ListBox. Эти переопределенные цвета нужно помещать в стиль ListBoxItem:
Самое интересное, что у кого-то до сих пор это работает в таком же виде! Вот скриншот прислали мне только что [img=]

К сообщению приложен файл. Размер - 63Kb
11 окт 18, 16:10    [21701752]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3167
это зависит от выбранной темы Windows, скорее всего
11 окт 18, 17:09    [21701825]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
это зависит от выбранной темы Windows, скорее всего
Я тоже пришёл к такому мнению. Но мне прислали только скрин и не ответили на вопрос о системе, версиях VS и FW.
11 окт 18, 18:41    [21701904]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4604
Миль пардон, ошибся. Заглянул в документацию - поиск ресурсов ведется не по визуальному дереву, а по логическому, и в случае DynamicResource (в дефолтном теплейте ListBoxItem цвета адресуются именно через DynamicResource) поиск ведется и в стилях, и шаблонах.
Единственный мутный момент, плохо разъясненный в документации - вот этот:
1. The lookup process checks for the requested key within the resource dictionary defined by the element that sets the property.
- If the element defines a Style property, the Resources dictionary within the Style is checked.
- If the element defines a Template property, the Resources dictionary within the FrameworkTemplate is checked.
2. The lookup process then traverses the logical tree upward, to the parent element and its resource dictionary. This continues until the root element is reached.

- т.е. ресурсы в стилях и шаблонах ищутся только несоредственно у элемента, запрашивающего ресурс. Однако, учитывая, что вот это тоже вполне работает:
<Grid>
  <Grid.Style>
    <Style>
      <Style.Resources>
        <!-- Item TextColor -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#0505F3" />
        <!-- Background of selected item when focussed -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00FF3D" />
        <!-- Background of selected item when not focussed -->
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#3F8257" />
      </Style.Resources>
    </Style>
  </Grid.Style>
  <ListBox>
    <ListBoxItem Content="Строка Один"/>
    <ListBoxItem Content="Строка Два"/>
    <ListBoxItem Content="Строка Три"/>
    <ListBoxItem Content="Строка Четыре"/>
    <ListBoxItem Content="Строка Пять"/>
  </ListBox>
</Grid>

можно сделать вывод, что документация недоговоравает - поиск в стилях и словарях делается в каждом элементе траверса поиска в логическом дереве.
Так что исходный пример вполне рабочий (и у меня он тоже работает). Системные стили и темы здесь вряд ли играют какое-то значение, т.к. в них процесс поиска заглядывает только тогда, когда ничего не нашлось ни в логическом дереве, ни в ресурсах приложения, а здесь всё вполне должно найтись. Скорее всего, где-то переопределен стандартный шаблон ListBoxItem.
12 окт 18, 11:28    [21702309]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны!
Мне дали ещё такое разъяснение.

Мой скриншот выше сделан на семерке, сейчас попробовал на десятке — тоже не работает.

Дефолтный стиль ListBoxItem на семерке:
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Padding" Value="2,0,0,0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <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>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsSelected" Value="true"/>
                                    <Condition Property="Selector.IsSelectionActive" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
Все требуемые ключи для переопределения в наличии.

Дефолтный стиль на десятке:
        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
        <SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Padding" Value="4,1"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <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="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Border}"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Border}"/>
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
Как видим, используются другие ключи, да еще и как StaticResource вместо DynamicResource, а поскольку объявлены эти кисти ближе к дефолтному стилю, постольку они и используются.
Наверное, в этом случае проще переопределить стиль (шаблон — выше).
12 окт 18, 13:56    [21702501]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны, какое Ваше мнение на этот счёт?
Лучшее решение переопределить стиль с использованием триггеров для IsSelected и IsSelectionActive?
Или какой-то иной подход надо использовать для этого случая?
12 окт 18, 14:00    [21702506]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4604
Eld Hasp
Мой скриншот выше сделан на семерке, сейчас попробовал на десятке — тоже не работает.

Т.е. не работает и на 7, и на 10? Или на 7 работает, на 10 не работает?
Если первое - не знаю, у меня на Win7 работает вполне нормально.
Если второе, то это легко объяснимо - static resources lookup работает только по ресурсным словарям, объявленным непосредственно в элементах, и не заглядывет в стили и шаблоны элементов, поэтому дефолтный шаблон на Win10 даже и не думает смотреть на объявленные вами стили, и на цвета внутри них. И это, кстати, еще одно доказательство того, почему переопределение системных ключей - не лучший выход: надо всегда знать, как устроен дефолтный шаблон в текущем окружении, и быть готовым к тому, что при смене версии ОС, или при очередном сервис-паке всё это вдруг перестанет работать. А вариант со стилем, где цвета заданы в триггерах, будет работать всегда.
12 окт 18, 14:23    [21702544]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3167
Eld Hasp,

я обычно такие вещи делаю через триггеры, чем долбаться с этими системными кистями и ловить баги в разных системах.
Еще хочу обратить ваше внимание на такую штуку как VisualStateManager
12 окт 18, 15:00    [21702607]     Ответить | Цитировать Сообщить модератору
 Re: Цвет выделенного элемента в ListBox  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны
Eld Hasp
Мой скриншот выше сделан на семерке, сейчас попробовал на десятке — тоже не работает.

Т.е. не работает и на 7, и на 10? Или на 7 работает, на 10 не работает?
На 7-ке работает. Как и у Вас.
Сон Веры Павловны
А вариант со стилем, где цвета заданы в триггерах, будет работать всегда.
Roman Mejtes
я обычно такие вещи делаю через триггеры
Понял вас. Подобное надо делать через триггера. Так и буду делать.
Спасибо за советы и помощь!
13 окт 18, 01:08    [21703121]     Ответить | Цитировать Сообщить модератору
Все форумы / WPF, Silverlight Ответить