michalt38
michalt38

Reputation: 1193

Display row numbers in ListView UWP

I'm looking for a solution to display row numbers for every element in ListView. What's more, the row numbers need to be updated after some element is deleted from the list or when the elements are moved to another positions. I'm using UWP (C++).

Upvotes: 0

Views: 304

Answers (1)

YanGu
YanGu

Reputation: 3032

If you want to display row numbers in a ListView, we suggest you to use data binding. You could refer to the document: XAML controls; bind to a C++/WinRT property and XAML items controls; bind to a C++/WinRT collection for detailed code about data binding.

Take the project Bookstore implemented in the above documents as an example, we need to change the content of each item in a ListView by using DataTemplate, and update the index of each item when the IObservableVector instance(which is the data binding source of the ListView) changes by adding the IObservableVector<T>.VectorChanged event.

For example:

  1. Add a property representing the index of each item in the ListView.

BookSku.idl

    runtimeclass BookSku : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        ……
        Int16 Index;
    }

BookSku.h

struct BookSku : BookSkuT<BookSku>
{
    ……
    int16_t Index();
    void Index(int16_t value);

private:
    ……
    int16_t m_index = 0;
};

BookSku.cpp

int16_t BookSku::Index()
{
    return m_index;
}
void BookSku::Index(int16_t value)
{
    if (m_index != value)
    {
        m_index = value;
        m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Index" });
    }
}
  1. Initiate the Index property when initiate the m_bookSkus , and add the VectorChanged event for m_bookSkus to update the index when the items of m_bookSkus changes.

BookstoreViewModel.cpp

    BookstoreViewModel::BookstoreViewModel()
    {
        m_bookSkus = winrt::single_threaded_observable_vector<Bookstore::BookSku>();
        m_bookSkus.VectorChanged([](IObservableVector<Bookstore::BookSku> const& sender, IVectorChangedEventArgs const& args) {

        for (int16_t i = 0; i < sender.Size(); i++)
        {
             auto item = sender.GetAt(i);
             item.Index(i+1);
        }

        });

    int16_t index=0;
    
    m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Title1");
    index = m_bookSkus.Size() + 1;
    m_bookSku.Index(index);

    m_bookSkus.Append(m_bookSku);

    m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Title2");
    index = m_bookSkus.Size() + 1;
    m_bookSku.Index(index);

    m_bookSkus.Append(m_bookSku);

    m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Title3");
    index = m_bookSkus.Size() + 1;
    m_bookSku.Index(index);

    m_bookSkus.Append(m_bookSku);
}
  1. Display the index in each item of the ListView by using DataTemplate in XAML.

MainPage.xaml

    <ListView ItemsSource="{x:Bind MainViewModel.BookSkus}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:BookSku">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{x:Bind Index,Mode=OneWay}" Margin="0,0,10,0"/>
                    <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

You could refer to the document for more information about DataTemplate, and refer to the document for more information about handing events by using delegates in C++/WinRT.

Upvotes: 1

Related Questions