Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListView reorder items doesn't trigger VectorChanged with winrt #8748

Open
HunterB06 opened this issue Aug 11, 2023 · 4 comments
Open

ListView reorder items doesn't trigger VectorChanged with winrt #8748

HunterB06 opened this issue Aug 11, 2023 · 4 comments
Labels
bug Something isn't working team-Controls Issue for the Controls team

Comments

@HunterB06
Copy link

Describe the bug

If you try to bind a ListView.ItemsSource to an IObservableVector, reordering the items from the UI with drag and drop won't update the data source behind. However, this works as expected if you do so in C# with an ObservableCollection.

Because of that, as soon as you reorder the list view in the UI, there is a inconsistency between what is shown and the actual collection. It should be easy to allow the user to reorder item, but because of this bug, it is not at all.

Steps to reproduce the bug

To repro the issue, you can test those 2 sample projects. The first one is in winrt with an ObservableVector, and the second one is in C# with a ObservableCollection. Both contain the same ListView:

<ListView
    ItemsSource="{x:Bind Layers}"
    CanReorderItems="True"
    CanDragItems="True"1
    ReorderMode="Enabled"
    AllowDrop="True"
    IsSwipeEnabled="True">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <TextBlock Text="{x:Bind  Mode=OneWay}"></TextBlock>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And the same setup for the collection:

MainPage()
    : m_layers{ winrt::single_threaded_observable_vector<winrt::hstring>() }
{
    m_layers.Append(L"ABC");
    m_layers.Append(L"DEF");
    m_layers.Append(L"GHI");
    m_layers.Append(L"JKL");

    m_layers.VectorChanged(winrt::auto_revoke, { this, &MainPage::OnLayersVectorChanged });
}

ReorderListViewSample.zip
ListViewReoderCSharp.zip

But if you but a breakpoint in the CollectionChanged method, you will see that it is called in the C# project, but not in the C++ winrt one.

Expected behavior

Reordering a ListView from a winrt project should, as with an ObservableCollection, trigger the VectorChanged event, and actually update the source collection (bound to ItemsSource).

Screenshots

No response

NuGet package version

None

Windows version

Windows 11 (22H2): Build 22621

Additional context

No response

@HO-COOH
Copy link

HO-COOH commented Jun 2, 2024

It's because you registered the event with winrt::auto_revoke, that returns a winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring>::VectorChanged_revoker that automatically revokes the event handler on destruction. So that your handler won't get called. To fix it, simply save it to a class member

    struct MainPage : MainPageT<MainPage>
    {
        MainPage()
            : m_layers{ winrt::single_threaded_observable_vector<winrt::hstring>() }
        {
            ...
            m_revoker = m_layers.VectorChanged(winrt::auto_revoke, { this, &MainPage::OnLayersVectorChanged });
        }
        ...
    private:
        winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring>::VectorChanged_revoker m_revoker;
    ...
};

@acouvert
Copy link

acouvert commented Jun 3, 2024

@HO-COOH, I believe this is a typo in the bug description. Looking at the provided sample application you'll found out that the revoker is saved into a class member as you suggested:
image

@HO-COOH
Copy link

HO-COOH commented Jun 3, 2024

@acouvert I don't see that line in the zip
image
he provided.
After I added that revoker, the issue is gone, the handler is called. No bug in the winui side

@acouvert-msft
Copy link

My bad, I realized that I was looking at an old archive from when the bug had been submitted. I may have looked at the bug in the past and came to same conclusion that you but somehow, I forgot to share it back here 😅.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working team-Controls Issue for the Controls team
Projects
None yet
Development

No branches or pull requests

5 participants