Sorting Listview resets the SelectedItem property

Richard Zhang-MSFT 6,936 Reputation points Microsoft Employee Moderator
2019-12-13T07:06:25.357+00:00

Source Link: MSDN

---

Hi,

basically I stumbled across this issue:

https://bengribaudo.com/blog/2010/09/14/199/keeping-selected-item-selected-when-changing-listviews-itemssource/comment-page-1?unapproved=88417&moderation-hash=4f244e91363349e3b625ff44be716cb2#comment-88417

I've got a ListView that I want to sort. I want to keep the selecteditem selected after the sorting operation. The problem I have is that the selecteditem is reset for a very small time to null, that I want to avoid, because other bindings rely on this property. This issue is described in the last part of the post, but not solved.

I tried to add an additional _isSorting boolean, without luck:

private void SortConversations()  
{  
    _isSorting = true;  
    _conversations.Sort(model => model.LastMessageTimeStamp, descending: true);  
    _isSorting = false;  
}  
  
public ConversationViewModel SelectedConversation  
{  
    get => _selectedConversation;  
    set  
    {  
        if (!_isSorting)  
        {  
            Set(ref _selectedConversation, value);  
        }  
    }  
}  

The problem is, that the Item does not appear as selected in the UI. Even if I try to manually set it again, it requires some additional Task.Delay() between the sort and the (re)selection. That is no proper solution, especially if the pc running the app is slower or faster.

---

I've already tried all the solutions you described. I am using an observable collection and Move() the items. I've also tried to backup the SelectedItem, but as I said it is null for a small time amount. And If I reselect the item, I need to add a delay between the Sorting and the reselection. And that is exactly the problem I am facing. How can I solve this?

I've prepared a minimal example, so you can test the problem real quick:

https://github.com/AtosNicoS/ListViewSortIssue

To reproduce the issue:

  1. Click "Reset" Button
  2. Select any item
  3. Click "Sort" Button
  4. Watch and Repeat

What you will see is, that sometimes (50% of the time) after the sorting a wrong(!!) item gets selected. With the additional delay, the correct item will be selected after one second. That is one issue I am focussing.

The other issue is, that SelectedItem is reset to null while sorting the list. I've added code to work around this issue with the _isSorting boolean. It is currently not activated, but should work commented out. You said, observable collections should work better here - they do not. The value is still null. And the issue even becomes more complicated, combined with the delay issue described above.

In my real application (with more data and larger datatemplates) this issue becomes even more complicated. If the selected item is at the top of the list, the sorting+selection works without delay, if it is in the bottom of the list, the item is not selected after sorting anymore.

Adding a delay does not sound like the right solution. I somehow need to wait until the ListView refreshed its items.

Any ideas?

Developer technologies | Universal Windows Platform (UWP)
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Richard Zhang-MSFT 6,936 Reputation points Microsoft Employee Moderator
    2019-12-13T07:13:09.99+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    The list items generated with the ObservableCollection will have UI reuse. This is the way ListView saves system resources.

    I tested your code and found a place that could cause conflict:

    Imgur

    Here you bind the ListViewItemViewModel.IsSelected property of ListViewItem.IsSelected.

    After I tried to replace ListViewItem with Grid and removed the IsSelected property binding, everything worked fine and we didn't need to set ListView.ItemsSource to null.

    Here I can give you some suggestions:

    1. If the IsSelected property is only a property for create the UI effects, it is recommended to delete.

    First, you can get the selected item directly by getting ListView.SelectedItem.

    Second, you can get the selected item through the ListView.ItemClick or ListView.SelectionChanged event and save it as a variable.

    2. If the IsSelected property will affect other data structures.

    You can also adjust the property in ListView.ItemClick or ListView.SelectionChanged, but do not let it directly bind to UI related properties.

    ---

    XAML code is in the txt attachment file.

    Regarding the inability to insert XML Code, check out this linked solution

    Thanks


  2. Nico Schulz 21 Reputation points
    2020-08-12T09:11:10.477+00:00

    It looks like this post was migrated from: https://social.msdn.microsoft.com/Forums/en-US/769e0497-5dc0-4816-b0a6-3f58a7690a63/sorting-listview-resets-the-selecteditem-property?forum=wpdevelop

    As I've stated, the issue still exists and I would really like to have that bug fixed, if possible.

    0 comments No comments

  3. Nico Schulz 21 Reputation points
    2021-04-06T11:43:41.283+00:00

    push The issue is still valid
    I also created an issue on github now: https://github.com/microsoft/microsoft-ui-xaml/issues/4751

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.