禁用列表视图中的元素选择?
Posted
技术标签:
【中文标题】禁用列表视图中的元素选择?【英文标题】:Disable selection of an element in Listview? 【发布时间】:2012-04-03 20:12:57 【问题描述】:如何禁用列表视图中元素的选择?
我不想在单击 ListView 中的元素时更改背景。 你能帮帮我吗?
<ListView Name="milestone_listView" Margin="817,108,90,276" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ItemsSource="Binding">
<Grid Name="milestone_grid"></Grid>
</ListView>
【问题讨论】:
你的意思是在 ListView 中绑定一个选中的项吗? 您不希望选择任何项目还是只选择特定项目? 我不希望所有项目都可以选择。 检查一下,我认为也适用于列表视图。 ***.com/questions/1398559/… 【参考方案1】:通常我只是将SelectedItem
笔刷覆盖为透明,但如果您不想要选择功能,也可以使用ItemsControl 来显示您的列表
<ListView.Resources>
<SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey" Color="Transparent" />
<SolidColorBrush x:Key="x:Static SystemColors.ControlBrushKey" Color="Transparent" />
<SolidColorBrush x:Key="x:Static SystemColors.HighlightTextBrushKey" Color="Black" />
</ListView.Resources>
如果您确实使用 ItemsControl
,请注意默认情况下它不会实现虚拟化,因此如果需要,您必须使用 implement it yourself
【讨论】:
您回答的第二部分是一个非常糟糕的解决方法。当 ListView 模板在未来的版本中更新以在选择上做更多的事情(例如动画)时会发生什么?或者这对所有主题都有什么保证?【参考方案2】:如果您不希望任何项目可供选择,请使用 ItemsControl 而不是 ListView。
一个 ItemsControl 可以做任何 ListView 可以做的减去选择的事情。
编辑:
如果您需要 UI 虚拟化,您将需要使用 ItemsControl 做更多的事情。但我认为你现在不应该担心这个。从您的代码示例中,我什至认为您无论如何都不需要它。在需要时优化代码不要过早地尝试优化。目前,只需为作业使用正确的控件,即 ItemsControl。
【讨论】:
需要注意的是ItemsControl
默认不支持虚拟化,而ListView
支持
他可以为 ItemsControl ItemsPanel 添加一个虚拟化面板。
没错,不过有more to Virtualizing an ItemsControl than just using a VirtualizingStackPanel
是的,但这完全不是重点。如果您不想选择而不是通过列表控件破解您的方式,请使用 ItemsControl。如果您需要虚拟化,请使用 ItemsControl 中的虚拟化面板解决该问题。是的,它不是添加一个的单行解决方案,但它也不是火箭科学。
我在我的项目中使用了您的解决方案,但网格没有显示我在 .xaml.cs 中添加到网格的任何内容。有什么问题?【参考方案3】:
我使用的技巧是处理 SelectionChanged 事件并撤消选择,例如将 SelectedIndex 设置为 -1:
<ListView SelectionChanged="ListView_SelectionChanged" />
在代码隐藏中:
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
var listView = sender as ListView;
if (listView != null)
listView.SelectedIndex = -1;
【讨论】:
【参考方案4】:或者,您可以采取更简单的方法,将 ListViewItem 的 IsEnabled 属性设置为 False。
在下面的示例中,我在绑定到我的 ListView 的项目上有一个“锁定”属性。如果是这样,我使用以下数据触发器禁用关联的 ListViewItem,然后使用其他样式在视觉上区分它。
<ListView.Resources>
<Style TargetType="x:Type ListViewItem">
<Style.Triggers>
<DataTrigger Binding="Binding Path=Locked" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
【讨论】:
不幸的是,我不再使用 .NET,但我只能建议,也许以后的版本已经替换/弃用/破坏了功能......【参考方案5】:我通过将 IsHitTestVisible
设置为 false 来解决它。当然,它并不适用于所有可能的情况,但在某些情况下会有所帮助。
【讨论】:
这行得通,但它会禁用一切,所以如果您希望用户能够与之交互的项目、按钮等中有任何东西,它就行不通。【参考方案6】:此解决方案允许您在 ListViewItem 模板中设置某些元素,而不是通过阻止单击事件冒泡来触发行选择。
将此属性附加到元素。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace YourNamespaceName
public class CancelMouseBubbling : DependencyObject
public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
"Active",
typeof(bool),
typeof(CancelMouseBubbling),
new PropertyMetadata(false, ActivePropertyChanged));
/// <summary>
/// Subscribe to the events we need.
/// </summary>
private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
var element = d as FrameworkElement;
if (element != null)
if ((e.NewValue as bool?).GetValueOrDefault(false))
element.PreviewMouseLeftButtonDown += ElementOnPreviewMouseLeftButtonDown;
element.MouseLeftButtonDown += ElementOnMouseLeftButtonDown;
else
element.PreviewMouseLeftButtonDown -= ElementOnPreviewMouseLeftButtonDown;
element.MouseLeftButtonDown -= ElementOnMouseLeftButtonDown;
/// <summary>
/// Block some events from bubbling at the OriginalSource.
/// </summary>
private static void ElementOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
if (mouseButtonEventArgs.Source is Panel)
mouseButtonEventArgs.Handled = true;
/// <summary>
/// Block all clicks from going past the element CancelMouseBubbling is set on
/// </summary>
private static void ElementOnMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
mouseButtonEventArgs.Handled = true;
[AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(FrameworkElement))]
public static bool GetActive(DependencyObject @object)
return (bool)@object.GetValue(ActiveProperty);
public static void SetActive(DependencyObject @object, bool value)
@object.SetValue(ActiveProperty, value);
声明一个命名空间以便你可以访问它:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ut="clr-namespace:YourNamespaceName"></UserControl>
并将其附加到元素上。
<Border ut:CancelMouseBubbling.Active="True" Background="#55171717">
...
</Border>
【讨论】:
以上是关于禁用列表视图中的元素选择?的主要内容,如果未能解决你的问题,请参考以下文章