Wpf 是否禁用在Listview中选择元素?

Wpf 是否禁用在Listview中选择元素?,wpf,listview,Wpf,Listview,如何禁用Listview中元素的选择 我不想在ListView中单击元素时更改背景。 你能帮我吗 <ListView Name="milestone_listView" Margin="817,108,90,276" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ItemsSource="{Binding}"> <Grid Nam

如何禁用Listview中元素的选择

我不想在ListView中单击元素时更改背景。 你能帮我吗

<ListView Name="milestone_listView" Margin="817,108,90,276" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ItemsSource="{Binding}">
        <Grid Name="milestone_grid"></Grid>
    </ListView>

通常我只是覆盖
SelectedItem
笔刷以使其透明,不过如果不需要选择功能,也可以使用来显示列表

<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可以完成ListView在没有选择的情况下所能做的一切

编辑:


如果您需要UI虚拟化,则需要对ItemsControl进行更多操作。但我认为你现在不应该担心这个。从您的代码示例来看,我甚至认为您无论如何都不会需要它。在需要时优化代码不要过早地尝试优化。目前,只需对作业使用正确的控件,即Items控件。

我通过将
IshitteVisible
设置为false来解决此问题。当然,它并不适用于所有可能的情况,但在某些情况下它可能会有所帮助。

我使用的技巧是处理SelectionChanged事件并撤消选择,例如将SelectedIndex设置为-1:

<ListView SelectionChanged="ListView_SelectionChanged" />

此解决方案允许您设置ListViewItem模板中的某些元素,而不是通过阻止click事件冒泡来触发行选择

将此属性附加到元素

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);
        }
    }
}
<Border ut:CancelMouseBubbling.Active="True" Background="#55171717">
...
</Border>
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
名称空间YourNamespaceName
{
公共类CancelMouseBubling:DependencyObject
{
公共静态只读DependencyProperty ActiveProperty=DependencyProperty.RegisterAttached(
“活动”,
类型(bool),
类型(取消鼠标闪烁),
新的PropertyMetadata(false,ActivePropertyChanged));
/// 
///订阅我们需要的活动。
/// 
私有静态void ActivePropertyChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var元素=d作为框架元素;
if(元素!=null)
{
if((例如,NewValue作为bool?.getValuerDefault(false))
{
element.PreviewMouseLeftButtonDown+=ElementOnPreviewMouseLeftButtonDown;
element.MouseLeftButtonDown+=ElementOnMouseLeftButtonDown;
}
其他的
{
element.PreviewMouseLeftButtonDown-=ElementOnPreviewMouseLeftButtonDown;
element.MouseLeftButtonDown-=ElementOnMouseLeftButtonDown;
}
}
}
/// 
///阻止某些事件在OriginalSource冒泡。
/// 
私有静态void元素预览MouseLeftButtonDown(对象发送器,MouseButtonEventArgs MouseButtonEventArgs)
{
if(鼠标按钮ventargs.Source为面板)
{
mouseButtonEventArgs.Handled=true;
}
}
/// 
///阻止通过元素CancelMouseBubling的所有单击被设置为打开
/// 
私有静态void元素MouseLeftButtonDown(对象发送器,MouseButtonEventArgs MouseButtonEventArgs)
{
mouseButtonEventArgs.Handled=true;
}
[AttachedPropertyBrowsableForChildrenAttribute(includeDescentants=false)]
[AttachedPropertyBrowsableForType(typeof(FrameworkElement))]
公共静态bool GetActive(DependencyObject@object)
{
返回(bool)@object.GetValue(ActiveProperty);
}
公共静态void SetActive(DependencyObject@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>

并将其附加到元素

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);
        }
    }
}
<Border ut:CancelMouseBubbling.Active="True" Background="#55171717">
...
</Border>

...

或者,您可以采用更简单的方法将ListViewItem的IsEnabled属性设置为False

在下面的示例中,我在绑定到我的ListView的项上有一个“Locked”属性。如果这是真的,我将使用以下数据触发器禁用关联的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>


您的意思是在ListView中绑定一个选定的项目吗?您希望所有项目都不可选择还是只可选择特定的项目?我希望所有项目都不可选择。请检查此项,我认为也适用于ListView。应该注意的是,
ItemsControl
默认情况下不支持虚拟化,而
ListView
则不支持虚拟化。她可以为ItemsControl ItemsPanel添加虚拟化面板。这是真的,不过有肯定的,但这完全是多余的。如果您不想选择,请使用ItemsControl,而不是通过列表控件进行黑客攻击。如果需要虚拟化,请使用ItemsControl中的虚拟化面板解决该问题。是的,这不是一个添加一行的解决方案,但也不是火箭科学。我在我的项目中使用了你的解决方案,但是网格没有显示我在.xaml.cs中添加到网格中的任何内容。这有什么错?你回答的第二部分是一个非常糟糕的解决方法。当ListView模板在将来的版本中更新,以便在选择上做更多的事情(例如动画)时,会发生什么情况?或者,这对所有主题都有什么保证?这可以工作,但它会禁用所有内容,因此,如果您在项目、按钮等中有任何内容。您希望用户能够与之交互,它就不起作用了。不幸的是,我不再使用.NET了,但我只能建议,也许更高版本有r