如何禁用ListBox中的选择?
除非您需要 ListBox 的其他方面,否则您可以使用 ItemsControl . 它将项目放在 ItemsPanel 中,并且没有选择的概念 .
ListBox
ItemsControl
ItemsPanel
<ItemsControl ItemsSource="{Binding MyItems}" />
默认情况下, ItemsControl 不支持其子元素的虚拟化 . 如果您有很多项目,虚拟化可以减少内存使用并提高性能,在这种情况下,您可以使用方法2并设置 ListBox 或add virtualisation to your ItemsControl样式 .
或者,只需设置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>
您可以切换到使用 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>
虽然@Drew Noakes的答案是大多数情况下的快速解决方案,但设置x:静态画笔会带来一些缺陷 .
当您按照建议设置x:静态画笔时,列表框项目中的所有子控件都将继承此样式 .
这意味着,虽然这将禁用列表框项的突出显示,但它可能会导致子控件的不良影响 .
例如,如果您的ListBoxItem中有一个ComboBox,它将禁用鼠标而不是ComboBox中的突出显示 .
相反,请考虑为此stackoverflow线程中提到的解决方案中包含的Selected,Unselected和MouseOver事件设置VisualStates:Remove Control Highlight From ListBoxItem but not children controls .
-Frinny
Hallgeir Engen的答案是一个很好的解决方案,但问题是在回发后,所有项目都可以再次选择,因此它要求您在 Page_Load 中为每个ListItem添加disabled属性 .
但是甚至有更简单的解决方案 .
您可以这样做,而不是禁用所有ListItems禁用ListBox本身 once ,并且所有列表项也被禁用 . set Enabled为false, doesn't 禁用ListBox at all ,但在 Page_Load 中添加以下行:
this.listbox.Attributes.Add("disabled", "disabled");
回发后,项目 don't 变为可选项,因此您可以将此代码行放入:
if (!this.IsPostBack) { }
但是 all 项仍然是灰色叠加,所以如果要为 all 项着色,那么制作css类:
.ListItemColor option { color: Black; /*(default color for list item, if it is not disabled)*/ }
然后将ListBox的CssClass设置为上面的css类 . 如果你想为列表项目(但不是全部)着色,那么你将需要设置一些项目的样式,并通过源(标记)或代码(javascript,c#或Visual Basic)为每个项目赋予颜色 .
这里的答案相当不错,但我正在寻找一些略有不同的东西:我想要选择,但只是不希望它被展示(或以不同的方式展示) .
上面的解决方案对我来说不起作用(完全),所以我做了其他的事情:我为列表框使用了一种新样式,它完全重新定义了模板:
<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>
从那开始,您可以轻松地添加自己的选择突出显示,或者如果您根本不想要任何突出显示,则保留它 .
也许你需要ItemsControl的onlly功能?它不允许选择:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
Note: This solution does not disable selection by keyboard navigation or right clicking (即箭头键后跟空格键)
所有先前的答案要么删除能力选择completly(在运行时没有切换)或只是删除视觉效果,而不是选择 .
但是,如果您希望能够通过代码选择和显示选择,而不是通过用户输入,该怎么办?可能是您想要“冻结”用户的选择而不禁用整个列表框?
解决方案是将整个ItemsContentTemplate包装到没有可视化镶边的Button中 . 按钮的大小必须等于项目的大小,因此它完全被覆盖 . 现在使用按钮的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
您可以在列表框上方放置一个Textblock,它不会改变应用程序的外观,也不会允许选择任何项目 .
例如,在Windows Phone上运行的简单修复是选择将所选项设置为null:
<ListBox SelectionChanged="ListBox_SelectionChanged">
并在代码背后:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { (sender as ListBox).SelectedItem = null; }
对我来说最好的解决方案是
<ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Focusable" Value="True"/> <Setter Property="IsHitTestVisible" Value="False" /> </Style> </ListBox.ItemContainerStyle>
我找到了一个完美的方式 .将ListBox IsHitTestVisible设置为false,以便用户无法鼠标悬停或向下滚动或向上滚动 .Capture PreviewGotKeyboardFocus e.Handled = true,以便用户可以通过键盘选项卡,向上箭头,向下箭头选择项目 .
这样的优势:
ListBox项目前景不会变为灰色 .
ListBox Background可以设置为Transparent
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>
码
private void StudentsListBox_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { e.Handled = true; }
IsEnabled = false
要禁用列表框/下拉列表中的一个或多个选项,您可以添加“已禁用”属性,如下所示 . 这会阻止用户选择此选项,并获得灰色叠加层 .
ListItem item = new ListItem(yourvalue, yourkey); item.Attributes.Add("disabled","disabled"); lb1.Items.Add(item);
16 回答
方法1 - ItemsControl
除非您需要
ListBox
的其他方面,否则您可以使用ItemsControl
. 它将项目放在ItemsPanel
中,并且没有选择的概念 .默认情况下,
ItemsControl
不支持其子元素的虚拟化 . 如果您有很多项目,虚拟化可以减少内存使用并提高性能,在这种情况下,您可以使用方法2并设置ListBox
或add virtualisation to your ItemsControl样式 .方法2 - 样式ListBox
或者,只需设置ListBox的样式,使选择不可见 .
我找到了一个非常简单直接的解决方案,我希望它能帮到你
您可以切换到使用
ItemsControl
而不是ListBox
.ItemsControl
没有选择的概念,所以没有什么可以关闭的 .另一个值得考虑的选择是禁用ListBoxItems . 这可以通过设置ItemContainerStyle来完成,如下面的代码片段所示 .
如果您不希望文本为灰色,则可以通过使用以下键向样式的资源添加画笔来指定禁用的颜色:{x:Static SystemColors.GrayTextBrushKey} . 另一种解决方案是覆盖ListBoxItem控件模板 .
这也可以,如果我需要使用listbox而不是itemscontrol,但我只是显示不应该选择的项目,我使用:
虽然@Drew Noakes的答案是大多数情况下的快速解决方案,但设置x:静态画笔会带来一些缺陷 .
当您按照建议设置x:静态画笔时,列表框项目中的所有子控件都将继承此样式 .
这意味着,虽然这将禁用列表框项的突出显示,但它可能会导致子控件的不良影响 .
例如,如果您的ListBoxItem中有一个ComboBox,它将禁用鼠标而不是ComboBox中的突出显示 .
相反,请考虑为此stackoverflow线程中提到的解决方案中包含的Selected,Unselected和MouseOver事件设置VisualStates:Remove Control Highlight From ListBoxItem but not children controls .
-Frinny
Hallgeir Engen的答案是一个很好的解决方案,但问题是在回发后,所有项目都可以再次选择,因此它要求您在 Page_Load 中为每个ListItem添加disabled属性 .
但是甚至有更简单的解决方案 .
您可以这样做,而不是禁用所有ListItems禁用ListBox本身 once ,并且所有列表项也被禁用 . set Enabled为false, doesn't 禁用ListBox at all ,但在 Page_Load 中添加以下行:
回发后,项目 don't 变为可选项,因此您可以将此代码行放入:
但是 all 项仍然是灰色叠加,所以如果要为 all 项着色,那么制作css类:
然后将ListBox的CssClass设置为上面的css类 . 如果你想为列表项目(但不是全部)着色,那么你将需要设置一些项目的样式,并通过源(标记)或代码(javascript,c#或Visual Basic)为每个项目赋予颜色 .
这里的答案相当不错,但我正在寻找一些略有不同的东西:我想要选择,但只是不希望它被展示(或以不同的方式展示) .
上面的解决方案对我来说不起作用(完全),所以我做了其他的事情:我为列表框使用了一种新样式,它完全重新定义了模板:
从那开始,您可以轻松地添加自己的选择突出显示,或者如果您根本不想要任何突出显示,则保留它 .
也许你需要ItemsControl的onlly功能?它不允许选择:
Note: This solution does not disable selection by keyboard navigation or right clicking (即箭头键后跟空格键)
所有先前的答案要么删除能力选择completly(在运行时没有切换)或只是删除视觉效果,而不是选择 .
但是,如果您希望能够通过代码选择和显示选择,而不是通过用户输入,该怎么办?可能是您想要“冻结”用户的选择而不禁用整个列表框?
解决方案是将整个ItemsContentTemplate包装到没有可视化镶边的Button中 . 按钮的大小必须等于项目的大小,因此它完全被覆盖 . 现在使用按钮的IsEnabled-Property:
启用按钮以“冻结”项目的选择状态 . 这是因为启用按钮在它们冒泡到ListboxItem-Eventhandler之前会占用所有鼠标事件 . 您的ItemsDataTemplate仍将接收MouseEvents,因为它是按钮内容的一部分 .
禁用该按钮以通过单击更改选择 .
dartrax
您可以在列表框上方放置一个Textblock,它不会改变应用程序的外观,也不会允许选择任何项目 .
例如,在Windows Phone上运行的简单修复是选择将所选项设置为null:
并在代码背后:
对我来说最好的解决方案是
我找到了一个完美的方式 .
将ListBox IsHitTestVisible设置为false,以便用户无法鼠标悬停或向下滚动或向上滚动 .
Capture PreviewGotKeyboardFocus e.Handled = true,以便用户可以通过键盘选项卡,向上箭头,向下箭头选择项目 .
这样的优势:
ListBox项目前景不会变为灰色 .
ListBox Background可以设置为Transparent
Xmal位
码
IsEnabled = false
要禁用列表框/下拉列表中的一个或多个选项,您可以添加“已禁用”属性,如下所示 . 这会阻止用户选择此选项,并获得灰色叠加层 .