代码之家  ›  专栏  ›  技术社区  ›  Martin Konicek Phil Windley

wpf listview关闭选择

  •  102
  • Martin Konicek Phil Windley  · 技术社区  · 15 年前

    我有一个简单的WPF列表视图和一个简单的问题:

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

    ListView

    我希望单击时第1行与第0行的外观相同。

    可能相关:我可以设置悬停/选择的外观样式吗?用自定义纯色替换蓝色渐变悬停外观(第3行)。我找到了 this this 不幸的是没有帮助。

    (不使用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>
    
    11 回复  |  直到 6 年前
        1
  •  120
  •   rmoore    9 年前

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

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

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

    您可以通过多种方式执行此操作,从更改ListViewItem的 ControlTemplate 只需设置样式(更容易)。可以使用 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
  •  31
  •   Felix D.    7 年前

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

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

    如果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>
    
        3
  •  16
  •   Hayley Guillou    10 年前

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

    <ListView ItemsSource="{Binding Test}" >
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="Focusable" Value="False"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
    
        4
  •  12
  •   Ben Wilde    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触发器和isselected/isselectionactive多触发器,将下面的代码添加到样式中以替换默认模板,选择后将不会有任何视觉更改。

    关闭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
  •  11
  •   Martin Konicek Phil Windley    10 年前

    最简单的方法是:

    <Setter Property="Focusable" Value="false"/>
    
        6
  •  8
  •   Reddog    15 年前

    关于上述解决方案…我将使用多触发器允许鼠标悬空突出显示在选择后继续工作,这样您的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
  •  5
  •   Robert Mars_win    9 年前

    ListView的一个属性是 IsHitTestVisible . 取消检查。

        8
  •  5
  •   Bradley Burnside    8 年前

    好吧,比赛有点晚了,但是这些解决方案都没有像我想做的那样。 这些解决方案有几个问题

    1. 禁用ListView项,该项将修改样式并禁用所有子控件。
    2. 从命中测试堆栈中移除,即子控件永远不会得到鼠标悬停或单击。
    3. 使它不可聚焦,这很简单,对我不起作用?

    我想要一个带有分组标题的列表视图,并且每个列表视图项都应该是“信息性的”,不需要选择或悬停,但是列表视图项中有一个按钮,我希望它可以单击并悬停。

    所以,我真正想要的是,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
  •  1
  •   BCA    7 年前

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

    1. 完全替换“选定”的视觉指示(例如使用某种形状),而不仅仅是更改标准突出显示的颜色。
    2. 在数据模板中包括所选的指示以及模型的其他可视化表示,但是,
    3. 不希望将“IsSelectedItem”属性添加到模型类中,而需要在所有模型对象上手动操作该属性。
    4. 要求在ListView中可以选择项
    5. 还想替换ismouseover的可视表示

    如果您像我一样(将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 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

        10
  •  1
  •   Jorge Freitas    7 年前

    使用以下代码:

       <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
  •  0
  •   Saikat Chakraborty    6 年前

    下面的代码禁用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>