WPF:防止在 Shift + 箭头上选择 ListViewItem

Posted

技术标签:

【中文标题】WPF:防止在 Shift + 箭头上选择 ListViewItem【英文标题】:WPF: Prevent ListViewItem from being selected on Shift + Arrow 【发布时间】:2013-12-20 11:03:18 【问题描述】:

当我单击一个项目并按下(向下/向上)箭头时,如何防止 ListViewItem 被选中?我不想禁用它,我只是希望它不能在 Shift+Arrow 上选择。我的一些列表视图项需要可选,而另一些则不需要。

示例:

[列表视图项 1]

[列表视图项 2]

[列表视图项 3]

用户点击 ListviewItem1,它被选中。

用户然后按下 SHIFT+向下箭头,=> ListViewItem 2 未被选中。

此时,要么选择 ListViewItem3,要么可能需要另一个 SHIFT+DOWN ARROW 才能选择 ListViewItem3(只要它在某个时候被选中就没有关系)。

(在我的项目中,实际的 ListViewItem 2 实际上不是 1 行上的常规项目,它是一个垂直项目,仅在一列中跨越多行。我的 ListView 源具有非常不同的项目的复合集合;我正在尝试仅选择看似“常规行项目”的内容)

【问题讨论】:

你能分享来自这个 UI 元素的任何 XAML 吗? 【参考方案1】:

您可以通过使用您班级的Property 来完成此操作,例如IsSelected。这是Property 的示例代码。

public bool IsSelected

    get
    
        return isSelected;           //return the value of isSelected
    
    set
    
        if (isSelectable)            //if the item is allowed to be selected
                                    //then update the value of isSelected
            isSelected = value;
            PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
        
    

在此示例中,假设 "isSelectable" 是在初始化类时在构造函数中设置的值。如果您还没有实现INotifyPropertyChanged,则需要...并且需要声明PropertyChanged 事件。

此外,您还需要一个Style,它将ListView 项目的选择绑定到此属性。这是一个可以完成此操作的Style 示例。

<ListView.Resources>
    <Style TargetType="x:Type ListViewItem">
        <Setter Property="IsSelected" Value="Binding IsSelected, Mode=TwoWay"/>
    </Style>
</ListView.Resources>

您可以更进一步,还可以绑定到Focusable Property。这将使得当您按下 SHIFT+DOWN 时,它将跳过任何您无法选择的项目并选择下一个可选择的项目.我会以类似于以下的方式完成此操作。

public bool Focusable

    get
    
        return isSelectable;    //if the item is selectable, then it is focusable
    

您还需要在您的Style 中为此创建一个绑定,方法是创建一个额外的Setter。这可以通过以下方式完成,在与之前相同的 Style 内。

<Setter Property="Focusable" Value="Binding Focusable"/>

尝试使用和不使用最后一个 Setter,看看哪种实现最适合您的需求。

--------- 更新 ---------

如果您只想在鼠标点击时选择项目,您可以通过订阅 ListView PreviewMouseLeftButtonDown 事件来实现。在事件处理程序内部,您首先需要get the clicked item,然后在您的类上调用一个函数,该函数将覆盖选择。这是一个如何完成的示例。

此功能将存在于您的 UI 代码隐藏中,并且必须由您的 ListView 订阅:

private void myListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

    DependencyObject dep = (DependencyObject)e.OriginalSource;

    while ((dep != null) && !(dep is ListViewItem))
    
        dep = VisualTreeHelper.GetParent(dep);
    

    if (dep == null)
        return;

    object obj = myListView.ItemContainerGenerator.ItemFromContainer(dep);

    if (obj is MyClass)
    
        foreach (MyClass i in myListView.Items)
        i.OverrideSelect(false);    //unselect all items

        MyClass item = (MyClass)obj;
        item.OverrideSelect(true);      //select the item clicked
    

(注意:将“MyClass”替换为您的班级类型)。

这个函数将存在于你的类文件中:

public void OverrideSelect(bool selected)

    isSelected = selected;
    PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));

【讨论】:

非常感谢。如果我希望我的 ListViewItem 在单击时可选择但在 Shift+Arrow 上不可选择,该怎么办? @bayedbest 每当您想“仅在单击时”执行操作时,代码就会开始变得有些混乱,但我已根据您的额外要求尽我所能更新了我的答案。 太好了,谢谢。所以这会在点击时选择一个项目,它是否确保它不会以任何其他方式被选中? (就像不在拖动选择或 shift+箭头上一样) @bayedbest,是的,我想是的。我自己尝试过,无法拖动选择。您仍然无法根据原始解决方案在 shift+arrow 上进行选择。希望它涵盖所有情况。

以上是关于WPF:防止在 Shift + 箭头上选择 ListViewItem的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 WPF DataGrid 在项目更新时取消选择 SelectedItem?

想要文本框中的向上和向下箭头来更改列表框选择

VS高效开发快捷键

自己整理的idea快捷键

在idea中怎么不能使用shift键全部选中?

pycharm的一些常用快捷键