如何在ListBox中禁用选择?
如何在ListBox中禁用选择?
ItemsControl
如果你不需要ListBox
的其他方面,你可以使用ItemsControl
代替。它将项目放置在ItemsPanel
中,并且没有选择的概念。
<ItemsControl ItemsSource="{Binding MyItems}" />
默认情况下,ItemsControl
不支持其子元素的虚拟化。如果您有大量项目,虚拟化可以减少内存使用并提高性能,这种情况下您可以使用方法2并为 ListBox
设置样式,或者向您的 ItemsControl
添加虚拟化。
ListBox
设置样式或者,只需为 ListBox 设置样式,以使选择不可见。
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Resources>
<!-- SelectedItem with focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent" />
<!-- SelectedItem without focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent" />
<!-- SelectedItem text foreground -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
Color="Black" />
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</ListBox.Resources>
我找到了一个非常简单明了的解决方案,它对我很有用,我希望它也能对你有所帮助。
<ListBox ItemsSource="{Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Setter Property="IsHitTestVisible" Value="False" />
请添加这个额外的属性来移除鼠标悬停时的高亮显示效果: <Setter Property="IsHitTestVisible" Value="False" />
- DonBoitnott你可以考虑使用 ItemsControl
而不是 ListBox
。一个 ItemsControl
没有选择的概念,因此没有需要关闭的东西。
另一个值得考虑的选项是禁用ListBoxItems。可以通过设置ItemContainerStyle来实现,代码示例如下:
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
如果您不想将文本设置为灰色,可以通过在样式资源中添加刷子并使用以下键{x:Static SystemColors.GrayTextBrushKey}来指定禁用颜色。另一个解决方案是覆盖ListBoxItem控件模板。
如果我需要使用listbox而不是itemscontrol来显示不可选的项,则可以使用以下代码:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
这里有很好的答案,但我正在寻找略微不同的东西:我想要选择,但只是不希望它显示出来(或以不同的方式显示)。
以上的解决方案对我没有完全起作用,所以我做了另外一件事情:我为我的列表框使用了一个新样式,该样式完全重新定义了模板:
<Style x:Key="PlainListBoxStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
从这里开始,您可以轻松地添加自己的选择高亮,或者如果您不想要任何高亮,可以将其保留在原样。
ListBoxItem
的模板制作成一个ContentPresenter
即可,就像这样... "最初的回答"<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在我的情况下,我不想禁用用户与我的 ListBoxItems
内容的交互,所以设置 IsEnabled
的解决方案对我无效。
另一个解决方案试图通过覆盖与颜色相关的属性来重新设计 ListBoxItem
,但只适用于那些您确定模板使用这些属性的情况。这对于默认样式很好,但对于自定义样式则无效。
使用 ItemsControl
的解决方案会破坏太多其他内容,因为 ItemsControl
与标准 ListBox
有完全不同的外观,并且不支持虚拟化,这意味着您必须重新设计 ItemsPanel
。
以上方法不会改变 ListBox
的默认外观,也不会禁用数据模板中的项目,通过默认支持虚拟化,而且与应用程序中可能存在的任何样式无关。这是 KISS 原则。
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
<ListBox Name="StudentsListBox" ItemsSource="{Binding Students}" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderThickness="0" Background="Transparent" IsHitTestVisible="False" PreviewGotKeyboardFocus="StudentsListBox_PreviewGotKeyboardFocus">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="Yellow" />
<Setter TargetName="Bd" Property="BorderBrush" Value="Transparent" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Name="GradeBlock" Text="{Binding Grade}" FontSize="12" Margin="0,0,5,0"/>
<TextBlock Grid.Column="1" Name="NameTextBlock" Text="{Binding Name}" FontSize="12" TextWrapping="Wrap"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
代码
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}