Romasz
Romasz

Reputation: 29792

How to deselect ListViewItem programmatically?

I'm stumped with this little problem for a while. The ListView under W10 has some strange behavior I cannot understand. Consider a simple list:

<ListView Name="myList" ItemClick="myList_ItemClick" SelectionChanged="myList_SelectionChanged" IsItemClickEnabled="True">
    <ListView.Items>
        <TextBlock Text="First item"/>
        <TextBlock Text="Second item"/>
        <TextBlock Text="Third item"/>
        <TextBlock Text="Fifth item"/>
    </ListView.Items>
</ListView>

and the code behind:

private void myList_ItemClick(object sender, ItemClickEventArgs e)
{
    Debug.WriteLine("Clicked item");
    ListView list = sender as ListView;
    ListViewItem listItem = list.ContainerFromItem(e.ClickedItem) as ListViewItem;
    listItem.IsSelected = !listItem.IsSelected;
}

private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Debug.WriteLine($"Selection changed -> added = {e.AddedItems.Count}, removed = {e.RemovedItems.Count}, currently selected = {myList.SelectedItems.Count}");
}

The code above runs very well on W8.1, but on W10 I encounter a problem. Selecting a first item works ok, changing it also, but I cannot deselect an item - listview seems (from debug output) to deselect item and then select it again right away - you can see SelectionChanged event fired twice. Here is sample debug output:

Debug Output

Does somebody know what is going on? How to deselect the item in this case?

Upvotes: 5

Views: 8338

Answers (4)

Iain Ballard
Iain Ballard

Reputation: 4828

None of the above worked for me in UWP targeting build 17134.

I was trying to deselect on double click. Eventually, I found this:

ctor () { // wherever you are doing setup
    myList.SelectionMode = ListViewSelectionMode.Extended;
    myList.DoubleTapped += myList_DoubleTapped;
    myList.SelectionChanged += myList_SelectionChanged;
}

int deselect = 0;
private void myList_DoubleTapped(object sender, Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
{
    deselect = (e.PointerDeviceType == PointerDeviceType.Touch) ? 1 : 2;
    MyList.SelectedIndex = -1;
}

private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (deselect > 0)
    {
        myList.SelectedIndex = -1;
        deselect--;
    }
}

Using ListViewSelectionMode.Single doesn't work. Using a bool flag for deselect doesn't work.

If you need to clear the selection from an event that is not on the list view (e.g. from a Button):

deselect = 0;
existingPinList.SelectedIndex = -1;

UWP ¯\_(ツ)_/¯

Upvotes: 0

user7925882
user7925882

Reputation: 59

You can clear the selection in listview

listView1.SelectedItems[0].Focused = false;
listView1.SelectedItems[0].Selected = false;

For further details, check this article how to clear selection inside selectedIndex changed event

Upvotes: 0

Adrian Brown
Adrian Brown

Reputation: 73

I don't know whether this is due to an update but this works;

 ListViewItem item = listView1.SelectedItems[0];
//Do whatever you need to with item
item.Selected = false;

I encountered the same problem and the answer on this page guided me to try the above.

Upvotes: 1

Igor Ralic
Igor Ralic

Reputation: 15006

I'm assuming that there's a different order of events going on in UWP. Something like this:

Item not selected -> ItemClick event handler -> Item is selected -> SelectionChanged event -> Some other event -> No more SelectionChanged events as that item is already selected.

Item is selected -> ItemClick event handler -> Item is not selected -> SelectionChanged event -> Some other event -> SelectionChanged event fires again as the item is no longer selected.

Here's a bit of a dirty trick to make it work:

private void myList_ItemClick(object sender, ItemClickEventArgs e)
{
    Debug.WriteLine("Clicked item");
    ListView list = sender as ListView;
    ListViewItem listItem = list.ContainerFromItem(e.ClickedItem) as ListViewItem;

    if (listItem.IsSelected)
    {
        listItem.IsSelected = false;
        list.SelectionMode = ListViewSelectionMode.None;
    }
    else
    {
        list.SelectionMode = ListViewSelectionMode.Single;
        listItem.IsSelected = true;
    }
}

EDIT: The behavior for multiple selection already works as expected: the item is deselected on second click. No workarounds needed!

Upvotes: 6

Related Questions