【问题标题】:WPF: Prevent ListViewItem from being selected on Shift + ArrowWPF:防止在 Shift + 箭头上选择 ListViewItem
【发布时间】: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 吗?

标签: wpf listviewitem shift


【解决方案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 上进行选择。希望它涵盖所有情况。
猜你喜欢
  • 1970-01-01
  • 2012-05-24
  • 2011-12-20
  • 1970-01-01
  • 2012-04-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多