WPF ListView关闭选择

时间:2009-06-26 20:46:56

标签: wpf listview

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

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

ListView

我希望第1行在点击时看起来就像第0行。

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

(不使用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>

13 个答案:

答案 0 :(得分:123)

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

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

但是,如果您仍然需要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>

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

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

答案 1 :(得分:31)

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

Specifying the Selection Color, Content Alignment, and Background Color for items in a 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>

如果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>

答案 2 :(得分:17)

设置每个ListViewItem的样式,使Focusable设置为false。

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

答案 3 :(得分: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>

只需删除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>

答案 4 :(得分:12)

我发现最简单的方法:

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

答案 5 :(得分: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>

答案 6 :(得分:5)

列表视图的一个属性是IsHitTestVisible。 取消选中它。

答案 7 :(得分:5)

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

  1. 禁用ListViewItem,它会搞砸样式并禁用所有子控件
  2. 从命中测试堆栈中删除,即子控件永远不会鼠标悬停或单击
  3. 让它变得无法集中,这对我来说根本不起作用?
  4. 我想要一个带有分组标题的ListView,每个ListViewItem应该是&#39; informational&#39;没有选择或悬停,但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>
    

答案 8 :(得分:1)

这适用于可能遇到以下要求的其他人:

  1. 完全取代“选定”的视觉指示(例如使用某种形状),而不仅仅是改变标准高光的颜色
  2. 在DataTemplate中包含此选定的指示以及模型的其他可视化表示,但是,
  3. 不希望必须向模型类添加“IsSelectedItem”属性,并且需要在所有模型对象上手动操作该属性。
  4. 要求可在ListView中选择项目
  5. 还想替换IsMouseOver的可视化表示
  6. 如果你像我一样(使用WPF与.NET 4.5)并发现涉及样式触发器的解决方案根本不起作用,这是我的解决方案:

    以样式替换ListViewItem的ControlTemplate:

    <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

答案 9 :(得分:1)

使用下面的代码:

   <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>

答案 10 :(得分:0)

下面的代码禁用ListViewItem行选择,还允许添加填充,边距等。

<style>
  #grid>.k-pager-wrap.k-grid-pager {
    display: none;
  }
</style>
<div id="grid"></div>
<button onclick="javascript:$('#grid').data('kendoGrid').dataSource.read()">Refresh</button>
<script>
  $("#grid").kendoGrid({
    columns: [
      { field: "productName" },
      { field: "category" }
    ],
    dataSource: [
      { productName: "Tea", category: "Beverages" },
      { productName: "Coffee", category: "Beverages" },
      { productName: "Ham", category: "Food" },
      { productName: "Bread", category: "Food" }
    ],
    pageable: {
      pageSize: 3,
      alwaysVisible: false
    },
    autoBind: false
  });
</script>

答案 11 :(得分:0)

下面的代码禁用对ListViewItem的关注

result_list = list()
def find_reversals(lst):
    for word in lst:
        if word[::-1] in lst and word[::-1] not in result_list and word[::-1] != word:
            result_list.append(word)
    return result_list

lst = ['art', 'rat', 'radar', 'scam', 'tar', 'vista']
output = find_reversals(lst)
print(output)
['rat']

答案 12 :(得分:0)

        <ListView Grid.Row="1" ItemsSource="{Binding Properties}" >
            <!--Disable selection of items-->
            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="VerticalContentAlignment" Value="Center"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListViewItem}">
                                <Grid Background="{TemplateBinding Background}">
                                    <Border Name="Selection" Visibility="Collapsed" />
                                    <!-- This is used when GridView is put inside the ListView -->
                                    <GridViewRowPresenter Grid.RowSpan="2"
                                      Margin="{TemplateBinding Padding}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="90" DisplayMemberBinding="{Binding Name}"  />
                    <GridViewColumn Width="90" CellTemplateSelector="{StaticResource customCellTemplateSelector}"  />
                </GridView>
            </ListView.View>
        </ListView>