Настройка визуализации выделения в ListBox в WPF - PullRequest
2 голосов
/ 26 ноября 2011

У меня есть элемент управления с ListBox, как это:

<local:MyControl x:Name="LayoutRoot" ...>

  <local:MyControl.Resources>
    <ItemsPanelTemplate x:Key="myTemplate">
      <StackPanel Background="Yellow"/>
    </ItemsPanelTemplate>
  </local:MyControl.Resources>

  <Border>    
    ...
    <ListBox  ItemsPanel="{DynamicResource myTemplate}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Rectangle Height="50" Width="200" Margin="10" Fill="Red"/>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
    ...
  </Border>
</local:MyControl>

Вот как это выглядит, когда я запускаю его:

enter image description here

ListBox рисует «рамку» вокруг каждого элемента в зависимости от их состояния:

  • Не выбрано: прозрачный
  • Выбранный и ListBox в фокусе: синий
  • Выбранный и ListBox не в фокусе: белый

Полагаю, "рамка" - это видимая часть фона ListBoxItem под полем объекта Rectangle, но я не уверен.

Я бы хотел настроить внешний вид "frame" -s для каждого отдельного состояния. Не могли бы вы привести пример, как это сделать?

Ответы [ 3 ]

2 голосов
/ 26 ноября 2011

Если вы используете Expression Blend, здесь - это то, как это сделать.

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

<Style TargetType="{x:Type ListViewItem}">
     <Style.Resources>
         <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00000000"/>
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#00000000"/>
     </Style.Resources>
</Style>

Обратите внимание, что я использую ListView вместо ListBox . Просто добавьте это к ближайшему блоку ресурсов.В моем случае это был <Window.Resources></Window.Resources> Кроме того, не стесняйтесь экспериментировать с цветами.Я пробовал что-то, что не делает ничего выдающего, когда выбран элемент.

ОБНОВЛЕНИЕ : Несмотря на то, что я использую ListView здесь, я думаю, что этот подход должен работать нормально даже для ListBox.Это потому, что я пытался установить свойства объекта SystemColors, а не ListView.Попробуйте сделать это с помощью элемента управления List Box и отправьте сообщение обратно, если оно работает.

2 голосов
/ 26 ноября 2011

Это не «рамка», которую вы видите, а просто результат поля, установленного в вашем прямоугольнике. Обратите внимание, что вы не должны устанавливать прямоугольник как DataTemplate, иначе вы просто увидите ... прямоугольники в своем списке. Просто используйте для этого границу, в которую вы можете поместить свой контент (используя )

Чтобы получить правильные цвета, используйте стиль в ItemContainerStyle. Проблема в том, что триггеры не будет работать в случае «IsSelected» из-за того, что шаблон по умолчанию устанавливает синий цвет фона при выборе без возможности его изменения. Поэтому вы должны переопределить шаблон для того, чтобы этот BackGround не был виден, и определить триггеры внутри этого шаблона. Ваш стиль должен выглядеть примерно так:

    <Style x:Key="myStyle" TargetType="ListBoxItem" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border Background="{TemplateBinding Background}">
                        <Border Background="Red"  Margin="10">
                            <ContentControl Content="{Binding}" />
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="Black" />
                        </Trigger>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="Red" />
                        </Trigger>
                        <Trigger Property="IsFocused" Value="True">
                            <Setter Property="Background" Value="Orange" />
                        </Trigger>
                    </ControlTemplate.Triggers >
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

и теперь вы можете использовать этот стиль в своем ListBox с: ItemContainerStyle = "{StaticResource myStyle}"

Помните, что порядок ваших триггеров меняет результирующий цвет: последний выигрыш (например, для выбранного элемента и при наведении мыши)

1 голос
/ 26 ноября 2011

Вы можете играть с ItemContainerStyle, что в данном случае относится к каждому ListBoxItem:

<ItemsControl ...>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <!-- go nuts here if you want -->
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...