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



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

样品:

[ListViewItem1]

[ListViewItem2]

[ListViewItem3]

用户单击ListviewItem1,它就会被选中。

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

此时,要么选择了ListViewItem3,要么可能需要另一个SHIFT+DOWN箭头来选择ListViewItem3。

(在我的项目中,实际的ListViewItem 2实际上不是一行上的常规项,它是一个仅在一列中跨几行的垂直项。我的ListView源有一个非常不同的项的合成集合;我试图选择看起来只是"常规行项"的项)

您可以通过使用类的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
    }
}

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

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

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

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

如果您只想在单击鼠标时选择项目,可以通过订阅ListView PreviewMouseLeftButtonDown事件来完成。在事件处理程序内部,您需要首先获取单击的项,然后在类上调用一个函数,该函数将覆盖所选内容。下面是一个如何做到这一点的例子。

此功能将存在于您的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"));
}

最新更新