.net 没有 ListBox.SelectionMode="None",还有另一种方法可以禁用列表框中的选择吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1398559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
There is no ListBox.SelectionMode="None", is there another way to disable selection in a listbox?
提问by Shimmy Weitzhandler
How do I disable selection in a ListBox?
如何禁用列表框中的选择?
回答by Drew Noakes
Approach 1 - ItemsControl
方法 1 - ItemsControl
Unless you need other aspects of the ListBox, you could use ItemsControlinstead. It places items in the ItemsPaneland doesn't have the concept of selection.
除非您需要 的其他方面,否则您ListBox可以ItemsControl改用。它将项目放置在ItemsPanel并且没有选择的概念。
<ItemsControl ItemsSource="{Binding MyItems}" />
By default, ItemsControldoesn't support virtualization of its child elements. If you have a lot of items, virtualization can reduce memory usage and improve performance, in which case you could use approach 2 and style the ListBox, or add virtualisation to your ItemsControl.
默认情况下,ItemsControl不支持其子元素的虚拟化。如果你有很多的项目,虚拟化可以减少内存使用并提高性能,在这种情况下,你可以使用方法2和风格ListBox,或添加虚拟化到你ItemsControl。
Approach 2 - Styling ListBox
方法 2 - 样式 ListBox
Alternatively, just style the ListBox such that the selection is not visible.
或者,只需设置 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>
回答by Asad Durrani
I found a very simple and straight forward solution working for me, I hope it would do for you as well
我找到了一个对我有用的非常简单直接的解决方案,我希望它也对你有用
<ListBox ItemsSource="{Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
回答by Wilka
You could switch to using an ItemsControlinstead of a ListBox. An ItemsControlhas no concept of selection, so there's nothing to turn off.
您可以切换到使用 aItemsControl而不是 a ListBox。AnItemsControl没有选择的概念,所以没有什么可以关闭的。
回答by Caleb Vear
Another option worth considering is disabling the ListBoxItems. This can be done by setting the ItemContainerStyle as shown in the following snippet.
另一个值得考虑的选项是禁用 ListBoxItems。这可以通过设置 ItemContainerStyle 来完成,如下面的代码片段所示。
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
If you don't want the text to be grey you can specify the disabled color by adding a brush to the style's resources with the following key: {x:Static SystemColors.GrayTextBrushKey}. The other solution would be to override the ListBoxItem control template.
如果您不希望文本为灰色,您可以通过使用以下键向样式资源添加画笔来指定禁用的颜色:{x:Static SystemColors.GrayTextBrushKey}。另一种解决方案是覆盖 ListBoxItem 控件模板。
回答by Andrej Kikelj
This will also work, if I have the need to use listbox instead of itemscontrol, but am just displaying the items which shouldn't be selectable, I use:
这也将起作用,如果我需要使用列表框而不是 itemscontrol,但我只是显示不应该选择的项目,我使用:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
回答by Andreas Kahler
Quite good answers here, but I was looking for something slightly different: I want selection, but just do not want it to be shown (or shown in a different matter).
这里的答案非常好,但我正在寻找稍微不同的东西:我想要选择,但只是不想显示它(或以不同的方式显示)。
The solutions above did not work for me (completely), so I did something else: I used a new style for my listbox, which completely redefines the templates:
上面的解决方案对我不起作用(完全),所以我做了其他事情:我为我的列表框使用了一种新样式,它完全重新定义了模板:
<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>
Starting with that, you can easily add you own selection highlighting, or leave it like that if you dont want any at all.
从那开始,您可以轻松添加自己的选择突出显示,或者如果您根本不想要任何突出显示,则保持原样。
回答by Frinavale
While @Drew Noakes's answer is a quick solution for most cases there is a bit of a flaw that comes with setting the x:Static brushes.
虽然@Drew Noakes 的答案是大多数情况下的快速解决方案,但设置 x:Static 画笔时存在一些缺陷。
When you set the x:Static brushes as suggested, all of the children controls within the list box item will inherit this style.
当您按照建议设置 x:Static 画笔时,列表框项中的所有子控件都将继承此样式。
That means that, while this will work for disabling the highlighting of the list box item, it may result in undesired effects for the child controls.
这意味着,虽然这将用于禁用列表框项的突出显示,但它可能会对子控件产生不良影响。
For example, if you had a ComboBox within your ListBoxItem, it would disable the mouse over highlighting within the ComboBox.
例如,如果您的 ListBoxItem 中有一个 ComboBox,它将禁用鼠标悬停在 ComboBox 中的突出显示。
Instead, consider setting the VisualStates for the Selected, Unselected, and MouseOver events as covered in the solution mentioned in this stackoverflow thread: Remove Control Highlight From ListBoxItem but not children controls.
相反,请考虑为 Selected、Unselected 和 MouseOver 事件设置 VisualState,如此 stackoverflow 线程中提到的解决方案中所述:从 ListBoxItem 中移除控件突出显示,但不是子控件。
-Frinny
-弗林尼
回答by Mark A. Donohoe
I propose yet another solution. In my case, I don't want to disable user interaction with the contents of my ListBoxItemsso the solution to set IsEnabledwon't work for me.
我提出了另一种解决方案。就我而言,我不想禁用用户与我的内容的交互,ListBoxItems因此设置的解决方案IsEnabled对我不起作用。
The other solution that attempts to re-style the ListBoxItemby overriding the color-related properties only works for those instances where you're sure the template uses those properties. That's fine for default styles, but breaks with custom styles.
另一个尝试ListBoxItem通过覆盖与颜色相关的属性来重新设置样式的解决方案仅适用于您确定模板使用这些属性的那些实例。这适用于默认样式,但会破坏自定义样式。
Finally, the solution to use an ItemsControlbreaks too many other things as the ItemsControlhas a completely different look than a standard ListBoxand doesn't support virtualization, meaning you have to re-template the ItemsPanelanyway.
最后,使用 an 的解决方案ItemsControl打破了太多其他东西,因为ItemsControl它的外观与标准完全不同ListBox,并且不支持虚拟化,这意味着您ItemsPanel无论如何都必须重新模板化。
So my solution is just to simply re-template ListBoxItemto be nothing more than a ContentPresenter, like so...
所以我的解决方案只是简单地重新模板ListBoxItem成为一个ContentPresenter,就像这样......
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The above doesn't change the default look of the ListBox, doesn't disable items in the data templates for the ListBox, supports virtualization by default, and works independently of whatever styles may or may not be in use in your app. It's the KISS principle.
以上不会更改 的默认外观ListBox,不会禁用 的数据模板中的项目ListBox,默认支持虚拟化,并且独立于您的应用程序中可能使用或不使用的任何样式。这就是KISS原则。
回答by Sasha
Maybe you need onlly functionality of ItemsControl? It don't allow selection:
也许您只需要 ItemsControl 的功能?它不允许选择:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
回答by dartrax
Note: This solution does not disable selection by keyboard navigation or right clicking(ie. arrow keys followed by space key)
注意:此解决方案不会通过键盘导航或右键单击禁用选择(即箭头键后跟空格键)
All previous answers either remove the ability select completly (no switching in runtime) or simply remove the visual effect, but not the selection.
所有以前的答案要么完全删除能力选择(在运行时没有切换),要么只是删除视觉效果,而不是选择。
But what if you want to be able to select and show selection by code, but not by user input? May be you want to "freeze" the user's selection while not disabling the whole Listbox?
但是,如果您希望能够通过代码而不是通过用户输入来选择和显示选择,该怎么办?您可能想在不禁用整个列表框的情况下“冻结”用户的选择?
The solution is to wrap the whole ItemsContentTemplate into a Button that has no visual chrome. The size of the button must be equal to the size of the Item, so it's completely covered. Now use the button's IsEnabled-Property:
解决方案是将整个 ItemsContentTemplate 包装到一个没有可视化镶边的 Button 中。按钮的大小必须等于 Item 的大小,因此它被完全覆盖。现在使用按钮的 IsEnabled-Property:
Enable the button to "freeze" the item's Selection-state. This works because the enabled button eats all mouse events before they bubble up to the ListboxItem-Eventhandler. Your ItemsDataTemplate will still receive MouseEvents because it's part of the buttons content.
启用按钮以“冻结”项目的选择状态。这是有效的,因为启用的按钮会在它们冒泡到 ListboxItem-Eventhandler 之前吃掉所有鼠标事件。您的 ItemsDataTemplate 仍将接收 MouseEvents,因为它是按钮内容的一部分。
Disable the button to enable changing the selection by clicking.
禁用按钮以通过单击启用更改选择。
<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
达特拉克斯

