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

时间:2013-12-04 05:03:57

标签: wpf listviewitem shift

当我点击某个项目并按(向下/向上)箭头时,如何防止选择ListViewItem?我不想禁用它,我只是想让它在Shift + Arrow上无法选择。我的一些listviewitems需要是可选择的,而另一些则不需要。

样品:

[ListViewItem 1]

[ListViewItem 2]

[ListViewItem 3]

用户点击ListviewItem1,它被选中。

用户然后按SHIFT + DOWN ARROW,=>未选择ListViewItem 2.

此时选择了ListViewItem3,或者可能需要另一个SHIFT +向下箭头来选择ListViewItem3(只要它在某个时候被选中就无关紧要。)

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

1 个答案:

答案 0 :(得分:1)

您可以使用PropertyIsSelected来完成此操作。以下是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事件。

此外,您还需要StyleListView项目的选择绑定到此属性。以下是可以实现此目的的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
    }
}

您还需要通过创建额外的StyleSetter中为此创建绑定。这可以通过以下方式完成,与之前的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"));
}