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 99

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>

самый простой способ я нашел:

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

далее к решению выше... Я бы использовал Мультитриггер, чтобы основные моменты мыши продолжали работать после выбора, так что стиль вашего 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>

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

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

  1. отключить ListViewItem, который закручивает стили и отключает все дочерние элементы управления
  2. удалить из стека hit-test, т. е. дочерние элементы управления никогда не получают мыши или нажмите кнопку
  3. сделать это не фокус, это просто не работает для меня?

Я хотел 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>

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

  1. полностью замените визуальную индикацию "selected" (например, используйте какую-то форму), помимо простого изменения цвета стандартной подсветки
  2. включите эту выбранную индикацию в DataTemplate вместе с другими визуальными представлениями вашей модели, но,
  3. не нужно добавлять свойство "IsSelectedItem" в класс модели и обременять его вручную управление этим свойством для всех объектов модели.
  4. требуется, чтобы элементы выбирались в ListView
  5. также хотелось бы заменить визуальное представление 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 appearance