WPF ListView отключает выбор

У меня есть простой WPF ListView и простой вопрос:

Можно ли отключить выделение, чтобы, когда пользователь щелкает строку, строка не выделялась?

ListView

Мне бы хотелось, чтобы строка 1 при нажатии выглядела так же, как строка 0.

Возможно связано: могу ли я стилизовать вид наведения/выделения? Например. заменить синий вид градиента при наведении курсора (строка 3) на собственный сплошной цвет. Я обнаружил, что это и это, к сожалению, не помогает.

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

XAML для ListView:

<ListView Height="280" Name="listView">
    <ListView.Resources>
        <!-- attempt to override selection color -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightColorKey}"
                         Color="Green" />
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                <!-- more columns -->
            </GridView.Columns>
        </GridView>
     </ListView.View>
</ListView>

Ответ 1

В комментарии Мартина Коницека, чтобы полностью отключить выбор элементов самым простым способом:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

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

Вы можете сделать это несколькими способами: от изменения ListViewItem ControlTemplate до простого стиля (намного проще). Вы можете создать стиль для ListViewItems, используя ItemContainerStyle и "выключить" фон и кисть границы, когда он будет выбран.

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected"
                         Value="True">
                    <Setter Property="Background"
                            Value="{x:Null}" />
                    <Setter Property="BorderBrush"
                            Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

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

<GridViewColumn Header="IsSelected"
                DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />

Ответ 2

Ответ Moore не работает, а страница здесь:

Указание цвета выделения, выравнивания содержимого и цвета фона для элементов в ListBox

объясняет, почему он не может работать.

Если ваш список содержит только основной текст, самый простой способ решить проблему - использовать прозрачные кисти.

<Window.Resources>
  <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>
</Window.Resources>

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

  <Window.Resources>
    <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListViewItem}">
            <Border SnapsToDevicePixels="True" 
                    x:Name="Bd" 
                    Background="{TemplateBinding Background}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Padding="{TemplateBinding Padding}">
              <GridViewRowPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                    Columns="{TemplateBinding GridView.ColumnCollection}" 
                                    Content="{TemplateBinding Content}"/>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsEnabled" 
                       Value="False">
                <Setter Property="Foreground" 
                        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>

Ответ 3

Задайте стиль каждого элемента ListViewItem, чтобы значение параметра Focusable установлено равным false.

<ListView ItemsSource="{Binding Test}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

Ответ 4

Здесь шаблон по умолчанию для ListViewItem из Blend:

Шаблон списка по умолчанию 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>
                        <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>

Просто удалите IsSelected Trigger и IsSelected/IsSelectionActive MultiTrigger, добавив нижеприведенный код в свой стиль, чтобы заменить шаблон по умолчанию, и при его выборе визуального изменения не будет.

Решение отключить визуальные изменения свойства IsSelected:

    <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>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

Ответ 5

Самый простой способ найти:

<Setter Property="Focusable" Value="false"/>

Ответ 6

В дополнение к решению выше... Я бы использовал MultiTrigger, чтобы подсветка MouseOver продолжала работать после выбора, чтобы стиль ListViewItem был:

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True" />
                            <Condition Property="IsMouseOver" Value="False" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Background" Value="{x:Null}" />
                            <Setter Property="BorderBrush" Value="{x:Null}" />
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>

Ответ 7

Одним из свойств списка является IsHitTestVisible. Снимите флажок.

Ответ 8

Хорошо, немного поздно к игре, но ни одно из этих решений не сделало того, что я пытался сделать. У этих решений есть несколько проблем.

  • Отключите ListViewItem, который закручивает стили и отключает все элементы управления детьми.
  • Удалить из стека хитов, т.е. элементы управления детьми никогда не будут получать указатель мыши или нажмите
  • Сделать это не настраиваемым, это просто не работает для меня?

Мне нужен ListView с заголовками группировки, и каждый ListViewItem должен просто быть "информационным" без выбора или наведения, но в ListViewItem есть кнопка, в которой я хочу быть нажатой и иметь зависание.

Итак, действительно, я хочу, чтобы ListViewItem не был ListViewItem вообще, поэтому я перешел на ListViewItem ControlTemplate и просто сделал его простым ContentControl.

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ContentControl Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/>
                </ControlTemplate>
            </Setter.Value>
         </Setter>
     </Style>
</ListView.ItemContainerStyle>

Ответ 9

Это относится к тем, кто может столкнуться со следующими требованиями:

  • Полностью замените визуальную индикацию "выбрано" (например, используйте какую-то форму), за исключением изменения цвета стандартной подсветки
  • Включите эту выбранную индикацию в DataTemplate вместе с другими визуальными представлениями вашей модели, но
  • Не нужно добавлять свойство "IsSelectedItem" в класс модели и быть обремененным ручным манипулированием этим свойством для всех объектов модели.
  • Требовать элементы, которые можно выбрать в ListView
  • Также хотел бы заменить визуальное представление IsMouseOver

Если вы похожи на меня (используя WPF с .NET 4.5) и обнаружили, что решения, связанные с триггерами стиля, просто не работают, вот мое решение:

Замените ControlTemplate в ListViewItem в стиле:

<ListView ItemsSource="{Binding MyStrings}" ItemTemplate="{StaticResource dtStrings}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <ContentPresenter/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

.. И DataTemplate:

<DataTemplate x:Key="dtStrings">
        <Border Background="LightCoral" Width="80" Height="24" Margin="1">
            <Grid >
                <Border Grid.ColumnSpan="2" Background="#88FF0000" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsMouseOver, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}"/>
                <Rectangle Grid.Column="0" Fill="Lime" Width="10" HorizontalAlignment="Left" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}" />
                <TextBlock Grid.Column="1" Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
            </Grid>
        </Border>
    </DataTemplate>

Результаты в этом во время выполнения (элемент "B" выбран, элемент "D" имеет указатель мыши):

Внешний вид ListView

Ответ 10

Используйте код ниже:

   <ListView.ItemContainerStyle>
          <Style TargetType="{x:Type ListViewItem}">
           <Setter Property="Background" Value="Transparent'enter code here'" />
             <Setter Property="Template">
               <Setter.Value>
                 <ControlTemplate TargetType="{x:Type ListViewItem}">
                   <ContentPresenter />
                 </ControlTemplate>
               </Setter.Value>
             </Setter>
          </Style>
   </ListView.ItemContainerStyle>

Ответ 11

Приведенный ниже код отключает выбор строки ListViewItem, а также позволяет добавлять отступы, поля и т.д.

<ListView.ItemContainerStyle>                                                                              
   <Style TargetType="ListViewItem">                                                                                      
       <Setter Property="Template">                                                                                            
         <Setter.Value>                                                                                             
           <ControlTemplate TargetType="{x:Type ListViewItem}">                                                                                                    
              <ListViewItem Padding="0" Margin="0">                                                                                                        
                  <ContentPresenter />
              </ListViewItem>
           </ControlTemplate>                                                          
         </Setter.Value>                                                                                       
         </Setter>
      </Style>                                                                      
  </ListView.ItemContainerStyle> 

Ответ 12

Ниже код отключить Фокус на ListViewItem

<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>