WPF ListView关闭选择

Mar*_*cek 112 wpf listview

我有一个简单的WPF ListView和一个简单的问题:

是否可以关闭选择,因此当用户单击行时,该行不会突出显示?

列表显示

我希望第1行在单击时看起来像第0行.

可能相关:我可以设计悬停/选择的外观吗?例如.用自定义纯色替换蓝色渐变悬停外观(第3行).我发现这个这个,遗憾的是没有帮助.

(在不使用ListView的情况下实现相同也是可以接受的.我只是希望能够像ListView一样使用逻辑滚动和UI虚拟化)

ListView的XAML是:

<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>
Run Code Online (Sandbox Code Playgroud)

rmo*_*ore 129

根据Martin Konicek的评论,以最简单的方式完全禁用项目的选择:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>
Run Code Online (Sandbox Code Playgroud)

但是,如果您仍然需要ListView的功能,例如能够选择项目,那么您可以直观地禁用所选项目的样式,如下所示:

您可以通过多种方式执行此操作,从将ListViewItem的ControlTemplate更改为仅设置样式(更容易).您可以使用ItemContainerStyle为ListViewItems创建样式,并在选中后关闭背景和边框画笔.

<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>
Run Code Online (Sandbox Code Playgroud)

此外,除非您在选择项目时(或仅用于测试)通知用户,否则您可以添加一列来表示该值:

<GridViewColumn Header="IsSelected"
                DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
Run Code Online (Sandbox Code Playgroud)

  • 我现在解决得更好了 - <Setter Property ="Focusable"Value ="false"/>完全禁用选择行. (86认同)
  • 啊,我以为你的意思就是视觉上关闭选择.如果您根本不想要它们被选中,您可能需要查看使用ItemsControl(因为如果它们无法聚焦,您仍然可以通过代码设置所选项目),尽管让Grid看起来像你我必须做这样的事情:manicprogrammer.com/cs/blogs/...此外,如果你还没有,你可能想看看WPF Unleashed这本书,因为它提供了对WPF和XAML的精彩介绍. (8认同)
  • 没有看到相关部分,但你可以做同样的事情,在IsMouseOver属性上设置背景和边框. (2认同)
  • @MartinKonicek我知道这是一个老帖子,但你评价很高的评论应该是一个答案;) (2认同)

小智 31

摩尔的答案不起作用,这里的页面:

为ListBox中的项指定选择颜色,内容对齐和背景颜色

解释了为什么它不起作用.

如果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>
Run Code Online (Sandbox Code Playgroud)

如果listview的单元格保持控件(例如组合框),则会产生不良结果,因为它也会改变颜色.要解决此问题,您必须重新定义控件的模板.

  <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>
Run Code Online (Sandbox Code Playgroud)

  • 这使我的ListView中的所有项目都消失了 (14认同)

Hay*_*lou 18

设置每个ListViewItem的样式以将Focusable设置为false.

<ListView ItemsSource="{Binding Test}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
Run Code Online (Sandbox Code Playgroud)

  • 简单高效.它实际上做了所要求的:它关闭选择而不是隐藏它.这是最好的答案. (4认同)

Ben*_*lde 12

这是Blend的ListViewItem的默认模板:

默认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>
Run Code Online (Sandbox Code Playgroud)

只需删除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>
Run Code Online (Sandbox Code Playgroud)


Mar*_*cek 12

我发现最简单的方法:

<Setter Property="Focusable" Value="false"/>
Run Code Online (Sandbox Code Playgroud)

  • @Mutex它确实有效 - 你必须在`ListView.ItemContainerStyle`上应用它! (4认同)

Red*_*dog 8

继上面的解决方案......我会使用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>
Run Code Online (Sandbox Code Playgroud)


小智 5

listview的一个属性是IsHitTestVisible.取消选中它.

  • 我在列表视图项模板中得到了按钮模板。如果取消选择`IsHitTestVisible`,则无法点击按钮。它的作用类似于`IsEnabled = false;` (3认同)

小智 5

好吧,在比赛的最后阶段,但这些解决方案都没有做到我想做的事情.这些解决方案存在一些问题

  1. 禁用ListViewItem,它会搞砸样式并禁用所有子控件
  2. 从命中测试堆栈中删除,即子控件永远不会鼠标悬停或单击
  3. 让它无法集中精力,这简直对我不起作用?

我想要一个带有分组标题的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>
Run Code Online (Sandbox Code Playgroud)


Jor*_*tas 5

使用下面的代码:

<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>
</ListView.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)