我如何禁用列表框的选择?
IsEnabled = false
ItemsControl
除非你需要ListBox的其他方面,你可以使用ItemsControl代替。它将项目放在ItemsPanel中,并且没有选择的概念。
ListBox
ItemsPanel
<ItemsControl ItemsSource="{Binding MyItems}" />
默认情况下,ItemsControl不支持其子元素的虚拟化。如果有很多项,虚拟化可以减少内存使用并提高性能,在这种情况下,可以使用方法2并设置ListBox或添加虚拟化到你的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>
你可以切换到使用ItemsControl而不是ListBox。ItemsControl没有选择的概念,所以没有什么可以关闭。
注意:此解决方案不会禁用通过键盘导航或右键单击进行选择(即。方向键后接空格键)
所有之前的答案要么完全删除技能选择(运行时没有切换),要么只是删除视觉效果,但不删除选择。
但是,如果您希望能够通过代码而不是通过用户输入来选择和显示选择,该怎么办呢?也许你想“冻结”用户的选择,而不是禁用整个列表框?
启用按钮“冻结”项目的选择状态。这是可行的,因为启用按钮在鼠标事件冒泡到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>
dartrax
另一个值得考虑的选项是禁用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控件模板。
也许你只需要ItemsControl的功能?它不允许选择:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
你可以在你的列表框上面放置一个文本块,它不会改变你的应用程序的外观,也不允许选择任何项目。
我发现了一个非常简单和直接的解决方法,我希望它也适用于你
<ListBox ItemsSource="{Items}"> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Focusable" Value="False"/> </Style> </ListBox.ItemContainerStyle> </ListBox>
要禁用列表框/下拉菜单中的一个或多个选项,您可以添加“disabled”属性,如下所示。这阻止用户选择这个选项,它得到一个灰色的覆盖。
ListItem item = new ListItem(yourvalue, yourkey); item.Attributes.Add("disabled","disabled"); lb1.Items.Add(item);
虽然@Drew Noakes的回答是大多数情况下的快速解决方案,但设置x:静态笔刷有一点缺陷。
当您按照建议设置x:Static笔刷时,列表框项中的所有子控件都将继承此样式。
这意味着,虽然这将用于禁用列表框项的高亮显示,但它可能会导致子控件产生不希望看到的效果。
例如,如果你在ListBoxItem中有一个组合框,它将禁用鼠标在组合框中高亮显示。
相反,考虑设置已选、未选和MouseOver事件的VisualStates,就像这个stackoverflow线程:从ListBoxItem中删除控件高亮显示,但不删除子控件中提到的解决方案中所涉及的那样。
-Frinny
一个简单的修复工作在Windows Phone上,例如在选择设置选定项为空:
<ListBox SelectionChanged="ListBox_SelectionChanged">
在后面的代码中:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { (sender as ListBox).SelectedItem = null; }
这也将工作,如果我有需要使用列表框而不是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>
从那开始,你可以很容易地添加你自己的选择高亮,或者让它像这样,如果你不想要任何。
对我来说,最好的解决办法是:
<ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Focusable" Value="True"/> <Setter Property="IsHitTestVisible" Value="False" /> </Style> </ListBox.ItemContainerStyle>
我找到了一个完美的方法 将ListBox IsHitTestVisible设置为false,这样用户就不能用鼠标悬停或向下滚动或向上滚动 捕获PreviewGotKeyboardFocus e.Handled = true,这样用户就可以通过键盘Tab键,向上箭头,向下箭头来选择项目
这种方式的优点:
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; }
我提出另一种解决办法。简单地将ListBoxItem重新模板化为ContentPresenter,就像这样…
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
上述内容不会改变ListBox的默认外观,不会禁用ListBox的数据模板中的项,默认情况下支持虚拟化,并且独立于应用程序中可能使用或不使用的任何样式。这就是KISS原则。
这个方法有几个优点:
IsFocusable
IsHitTestVisible
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>