WPF ListView отключить выбор
У меня есть простой WPF 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>
10 ответов:
в комментарии Мартина Коничека, чтобы полностью отключить выбор элементов самым простым способом:
<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}" />
ответ Мура не работает, и страница здесь:
указание цвета выбора, выравнивания содержимого и цвета фона для элементов в списке
объясняет, почему он не может работать.
Если ваш listview содержит только основной текст, самый простой способ решить эту проблему - использовать прозрачные кисти.
<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>
это приведет к нежелательным результатам, если ячейки listview содержат элементы управления, такие как 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>
установите стиль каждого ListViewItem, чтобы иметь Фокусируемое значение false.
<ListView ItemsSource="{Binding Test}" > <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="Focusable" Value="False"/> </Style> </ListView.ItemContainerStyle> </ListView>
вот шаблон по умолчанию для 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 триггер и 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>
далее к решению выше... Я бы использовал Мультитриггер, чтобы основные моменты мыши продолжали работать после выбора, так что стиль вашего 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>
хорошо, немного поздно для игры, но ни одно из этих решений не сделало то, что я пытался сделать. Эти решения имеют пару проблем
- отключить ListViewItem, который закручивает стили и отключает все дочерние элементы управления
- удалить из стека hit-test, т. е. дочерние элементы управления никогда не получают мыши или нажмите кнопку
- сделать это не фокус, это просто не работает для меня?
Я хотел ListView с группировка заголовков, И каждый ListViewItem должен быть просто "информационным" без выбора или наведения указателя мыши, но в ListViewItem есть кнопка, которую я хочу щелкнуть и навести указатель мыши.
Итак, на самом деле я хочу, чтобы ListViewItem вообще не был ListViewItem, поэтому я поехал на ControlTemplate ListViewItem и просто сделал его простым 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>
использовать код ниже:
<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>
Это для тех, кто может столкнуться со следующими требованиями:
- полностью замените визуальную индикацию "selected" (например, используйте какую-то форму), помимо простого изменения цвета стандартной подсветки
- включите эту выбранную индикацию в 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 ' имеет мышь):