如何禁用ListBox中的选择?
答案 0 :(得分:251)
ItemsControl
除非您需要ListBox
的其他方面,否则您可以使用ItemsControl
。它将项目放在ItemsPanel
中,并且没有选择的概念。
<ItemsControl ItemsSource="{Binding MyItems}" />
默认情况下,ItemsControl
不支持其子元素的虚拟化。如果您有很多项目,虚拟化可以减少内存使用并提高性能,在这种情况下,您可以使用方法2并设置ListBox
或add virtualisation to your 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>
答案 1 :(得分:145)
我找到了一个非常简单直接的解决方案,我希望它能为你做到这一点
<ListBox ItemsSource="{Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
答案 2 :(得分:24)
您可以切换为使用ItemsControl
代替ListBox
。 ItemsControl
没有选择的概念,所以没有什么可以关闭的。
答案 3 :(得分:12)
另一个值得考虑的选择是禁用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控件模板。
答案 4 :(得分:7)
这也可以,如果我需要使用listbox而不是itemscontrol,但我只是显示不应该选择的项目,我使用:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
答案 5 :(得分:2)
虽然@Drew Noakes的答案是大多数情况下的快速解决方案,但设置x:静态画笔会带来一些缺陷。
按照建议设置x:静态画笔时,列表框项目中的所有子控件都将继承此样式。
这意味着,虽然这可用于禁用列表框项的突出显示,但它可能会导致子控件的不良影响。
例如,如果您的ListBoxItem中有一个ComboBox,它会禁用鼠标而不是ComboBox中的突出显示。
相反,请考虑为此stackoverflow线程中提到的解决方案中涵盖的Selected,Unselected和MouseOver事件设置VisualStates:Remove Control Highlight From ListBoxItem but not children controls。
-Frinny
答案 6 :(得分:1)
也许你需要ItemsControl的onlly功能?它不允许选择:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
答案 7 :(得分:1)
我提出了另一种解决方案。就我而言,我不想禁用用户与我的ListBoxItems
内容的交互,因此设置IsEnabled
的解决方案对我不起作用。
另一种尝试通过覆盖与颜色相关的属性来重新设置ListBoxItem
样式的解决方案,仅适用于您确定模板使用这些属性的情况。默认样式很好,但会与自定义样式一起破坏。
最后,使用ItemsControl
的解决方案会破坏很多其他事情,因为ItemsControl
的外观与标准ListBox
完全不同,并且不支持虚拟化,这意味着您拥有可以重新模板ItemsPanel
。
所以我的解决方案只是简单地将ListBoxItem
重新模板化为ContentPresenter
,就像这样……
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
以上内容不会更改ListBox
的默认外观,不会禁用ListBox
的数据模板中的项目,默认情况下支持虚拟化,并且可以独立于任何样式或您的应用可能未在使用中。这是KISS的原则。
答案 8 :(得分:0)
注意:此解决方案不会禁用键盘导航选择或右键单击(即箭头键后跟空格键)
之前的所有答案要么删除能力选择完全(在运行时没有切换),要么只是删除视觉效果,而不是选择。
但是,如果您希望能够通过代码选择和显示选择,而不是通过用户输入,该怎么办?您可能想要“冻结”用户的选择而不禁用整个列表框吗?
解决方案是将整个ItemsContentTemplate包装到没有可视铬的Button中。按钮的大小必须等于Item的大小,因此它完全被覆盖。 现在使用按钮的IsEnabled-Property:
启用按钮以“冻结”项目的选择状态。这是因为启用按钮在它们冒泡到ListboxItem-Eventhandler之前会占用所有鼠标事件。您的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>
dartrax
答案 9 :(得分:0)
您可以在列表框上方放置一个Textblock,它不会改变您的应用程序的外观,也不会允许选择任何项目。
答案 10 :(得分:0)
例如,在Windows Phone上运行的简单修复是选择将所选项设置为null:
<ListBox SelectionChanged="ListBox_SelectionChanged">
在后面的代码中:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedItem = null;
}
答案 11 :(得分:0)
对我来说,最好的解决方案是:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
答案 12 :(得分:0)
我找到了一个完美的方式
将ListBox IsHitTestVisible设置为false,以便用户无法鼠标悬停或向下滚动或向上滚动。
捕获PreviewGotKeyboardFocus e.Handled = true,以便用户可以通过键盘选项卡,向上箭头,向下箭头选择项目。
这种优势:
XmaI位
<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;
}
答案 13 :(得分:0)
这个有几个优点:
IsFocusable
、IsHitTestVisible
等不是这种情况。ListBoxItem
被禁用,但是 TextBlock.Foreground
属性设置了正确的颜色。结果:无法通过键盘或鼠标选择项目,并且颜色不是“灰色”,因为我们没有禁用整个控件。
<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>
答案 14 :(得分:-3)
IsEnabled = false
答案 15 :(得分:-3)
要禁用列表框/下拉列表中的一个或多个选项,您可以添加“已禁用”属性,如下所示。这样可以防止用户选择此选项,并获得灰色叠加。
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);