WPF ListViewclosuresselect

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

是否有可能closuresselect,所以当用户点击行,行不突出显示?

列表显示

我想第1行看起来就像行0点击。

可能的相关:我可以风格的hover/select的外观? 例如。 用自定义纯色replace蓝色渐变hover外观(第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> 

Per Martin Konicek的评论,以最简单的方式完全禁用这些项目的select:

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

但是,如果您仍然需要ListView的function,如能够select一个项目,那么您可以在视觉上禁用所选项目的样式,如下所示:

您可以通过多种方式来完成这一点,从更改ListViewItem的ControlTemplate到设置样式(更简单)。 您可以使用ItemContainerStyle为ListViewItems创build样式,并在选中时closures背景和边框笔刷。

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

此外,除非您有其他方式通知用户select项目(或仅用于testing),您可以添加一列来表示值:

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

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

为列表框中的项目指定select颜色,内容alignment和背景颜色

解释了为什么它不能工作。

如果你的列表视图只包含基本文本,解决这个问题最简单的方法就是使用透明画笔。

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

这将产生不良结果,如果列表视图的单元格持有控件,如combobox,因为它也会改变它们的颜色。 要解决这个问题,你必须重新定义控件的模板。

  <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的样式设置为将Focusable设置为false。

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

以下是来自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 MultiTrigger,将下面的代码添加到您的样式中以replace默认模板,并且在select时不会发生可视变化。

closuresIsSelected属性的可视化更改的解决scheme:

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

除了上面的解决scheme…我会使用一个MultiTrigger允许MouseOver高亮在select后继续工作,以便您的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 。 取消选中它。

好吧,游戏迟到了一点,但是这些解决scheme都没有做到我想要做的。 这些解决scheme有一些问题

  1. 禁用ListViewItem,这样会调整样式并禁用所有子控件
  2. 从命中testing堆栈中移除,也就是说,子控件永远不会被鼠标hover或点击
  3. 使它不能集中,这只是简单的不适合我?

我想要一个带有分组头的ListView,每个ListViewItem应该是没有select或hover的“信息”,但是ListViewItem有一个button,我想要点击鼠标并hover。

所以,我真正想要的是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> 

这是为其他可能遇到以下要求的人员:

  1. 完全replace“选定”的视觉指示(例如使用某种形状),而不仅仅是改变标准高光的颜色
  2. 在DataTemplate中包含此选定的指示以及您的模型的其他视觉表示,但是,
  3. 不希望为模型类添加一个“IsSelectedItem”属性,并且需要在所有模型对象上手动操作该属性。
  4. 要求项目在ListView中可选
  5. 也想replaceIsMouseOver的可视化表示

如果你像我一样(使用.NET 4.5的WPF),并发现涉及样式触发器的解决scheme根本不起作用,这是我的解决scheme:

以样式replaceListViewItem的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'有鼠标hover):

ListView外观