我如何禁用列表框的选择?
当前回答
对我来说,最好的解决办法是:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
其他回答
方法1 -项目控制
除非你需要ListBox的其他方面,你可以使用ItemsControl代替。它将项目放在ItemsPanel中,没有选择的概念。
<ItemsControl ItemsSource="{Binding MyItems}" />
默认情况下,ItemsControl不支持其子元素的虚拟化。如果你有很多项,虚拟化可以减少内存使用和提高性能,在这种情况下,你可以使用方法2和样式ListBox,或添加虚拟化到你的ItemsControl。
方法2 -样式化列表框
或者,只是样式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>
注意:这个解决方案不禁用选择键盘导航或右键单击(即。方向键后接空格键)
所有之前的答案要么完全删除技能选择(运行时没有切换),要么只是删除视觉效果,但不删除选择。
但是,如果您希望能够通过代码而不是通过用户输入来选择和显示选择,该怎么办呢?也许你想“冻结”用户的选择,而不是禁用整个列表框?
解决方案是将整个ItemsContentTemplate包装成一个没有视觉chrome的Button。按钮的大小必须等于Item的大小,所以它是完全覆盖的。 现在使用按钮的isenabled -属性:
启用按钮“冻结”项目的选择状态。这是可行的,因为启用按钮在鼠标事件冒泡到listboxitem - eventandler之前吃掉了所有的鼠标事件。你的ItemsDataTemplate仍然会收到MouseEvents,因为它是按钮内容的一部分。
禁用此按钮可通过单击更改选择。
<Style x:Key="LedCT" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button IsEnabled="{Binding IsSelectable, Converter={StaticResource BoolOppositeConverter}}" Template="{DynamicResource InvisibleButton}">
<ContentPresenter />
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="InvisibleButton" TargetType="{x:Type Button}">
<ContentPresenter/>
</ControlTemplate>
达特拉克斯
我找到了一个完美的方法。 将ListBox IsHitTestVisible设置为false,这样用户就不能用鼠标悬停或向下滚动或向上滚动。 捕获PreviewGotKeyboardFocus e.Handled = true,这样用户可以通过键盘Tab选择项目,箭头向上,箭头向下。
这种方式的优点:
列表框项目前景不会变成灰色。 ListBox背景可以设置为透明
xmal
<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>
code
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}
解决方案应该简单直接。
这个方法有几个优点:
键盘导航也被禁用。这不是IsFocusable, IsHitTestVisible等的情况。 没有“禁用”元素的视觉提示:只有ListBoxItem是禁用的,但TextBlock。前景色属性设置正确的颜色。
结果:无法通过键盘或鼠标选择项目,颜色也不是“灰色”,因为我们没有禁用整个控件。
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Foreground="Black" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这也将工作,如果我有需要使用列表框而不是itemscontrol,但只是显示不应该是可选的项目,我使用:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
推荐文章
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- AppSettings从.config文件中获取值
- 如何检查IEnumerable是否为空或空?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 如何在iis7应用程序池中设置。net Framework 4.5版本
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何指定最小值,但没有使用范围数据注释属性的最大小数?
- 如何在PowerShell中获得本地主机名?
- 为什么在Java和。net中不能修改字符串?
- 禁用Visual Studio 2015额外调试选项
- 'throw'和'throw new Exception()'的区别
- c# int到字节[]
- 如何跟踪log4net问题