Question

How do I prevent a ListViewItem from being selected when I click on an item and press (Down/Up) Arrow? I don't want to disable it, I just want it to not be selectable on Shift+Arrow. Some of my listviewitems need to be selectable and some others not.

Sample:

[ListViewItem 1]

[ListViewItem 2]

[ListViewItem 3]

User clicks on ListviewItem1, it gets selected.

User then presses SHIFT+DOWN ARROW,=> ListViewItem 2 is not selected.

At this point either ListViewItem3 is selected or it might take another SHIFT+DOWN ARROW to select ListViewItem3 (it doesn't matter as long as it gets selected sometime).

(In my project the actual ListViewItem 2 is actually NOT a regular item on 1 row, it is a vertical item that spans several rows in just one column. My ListView source has a compositecollection of very different items; I am trying to select what appears to be 'regular row items' only)

Was it helpful?

Solution

You can accomplish this by using a Property of your class such as IsSelected. Here is some sample code for what that Property would look like.

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"));
        }
    }
}

In this example it is assumed that "isSelectable" is a value that is set in the constructor when your class is being initialized. If you don't already have INotifyPropertyChanged implemented, it needs to be... and the PropertyChanged event needs to be declared.

In addition, you will also want a Style that binds the selection of ListView items to this property. Here is an example of a Style that could accomplish this.

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

You can take this one step further, and also bind to the Focusable Property. This will make it so that when you press SHIFT+DOWN it will skip any items that you cannot select and select the next item that is selectable. I would accomplish this in a manner similar to the following.

public bool Focusable
{
    get
    {
        return isSelectable;    //if the item is selectable, then it is focusable
    }
}

You would also need to create a binding for this in your Style by creating an additional Setter. This could be done the following way, inside the same Style as before.

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

Try it both with and without that last Setter and see which implementation suits your needs best.

--------- UPDATE ---------

If you would like to only select items on mouse click, you could do so by subscribing to the ListView PreviewMouseLeftButtonDown event. Inside of the event handler, you would need to first get the clicked item, and call a function on your class which will override the selection. Here is an example of how that is done.

This function would exist in your UI code-behind and must be subscribed to by your 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
    }
}

(Note: replace "MyClass" with your class type).

This function would exist in your class file:

public void OverrideSelect(bool selected)
{
    isSelected = selected;
    PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top