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>