modello di funzione WinRT:: single_threaded_observable_vector (C++/WinRT)winrt::single_threaded_observable_vector function template (C++/WinRT)

Modello di funzione che crea e restituisce un oggetto di un tipo che implementa una raccolta osservabile.A function template that creates and returns an object of a type that implements an observable collection. L'oggetto viene restituito come IObservableVector, che è l'interfaccia tramite la quale vengono chiamate le funzioni e le proprietà dell'oggetto restituito.The object is returned as an IObservableVector, and that's the interface via which you call the returned object's functions and properties.

È possibile passare facoltativamente un rvalue std:: Vector rvalue esistente nella funzione — passando un oggetto temporaneo o chiamando std:: Move su un lvalue.You can optionally pass an existing std::vector rvalue into the function—either pass a temporary object, or call std::move on an lvalue.

Per altre informazioni ed esempi di codice, vedere raccolte con C++/WinRT.For more info, and code examples, see Collections with C++/WinRT.

SintassiSyntax

template <typename T, typename Allocator = std::allocator<T>>
winrt::Windows::Foundation::Collections::IObservableVector<T> single_threaded_observable_vector(std::vector<T, Allocator>&& values = {})

Parametri di modelliTemplate parameters

typename T Tipo degli elementi della raccolta.typename T The type of the elements of the collection.

typename Allocator Tipo dell'allocatore del vettore dal quale inizializzare la raccolta, se ne viene passato uno, in caso contrario l'allocatore predefinito.typename Allocator The type of the allocator of the vector from which you initialize the collection, if you pass one, otherwise the default allocator.

ParametriParameters

values Riferimento facoltativo a un rvalue di tipo std:: Vector da cui inizializzare gli elementi dell'oggetto Collection.values An optional reference to an rvalue of type std::vector from which to initialize the elements of the collection object.

Valore restituitoReturn value

IObservableVector che rappresenta un nuovo oggetto Collection.An IObservableVector representing a new collection object.

RequisitiRequirements

SDK minimo supportato: Windows SDK versione 10.0.17763.0 (Windows 10, versione 1809)Minimum supported SDK: Windows SDK version 10.0.17763.0 (Windows 10, version 1809)

Spazio dei nomi: WinRTNamespace: winrt

L' intestazione % WindowsSdkDir% include <WindowsTargetPlatformVersion> \cppwinrt\winrt\base.h (incluso per impostazione predefinita)Header %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt\base.h (included by default)

Se si dispone di una versione precedente del Windows SDKIf you have an older version of the Windows SDK

Se non si ha la versione Windows SDK 10.0.17763.0 (Windows 10, versione 1809) o successiva, sarà necessario implementare il proprio modello di vettore osservabile per fungere da implementazione utile e per utilizzo generico di **IObservableVector < t > **.If you don't have the Windows SDK version 10.0.17763.0 (Windows 10, version 1809), or later, then you'll need to implement your own observable vector template to serve as a useful, general-purpose implementation of IObservableVector<T>. Di seguito è riportato un elenco di una classe denominata **single_threaded_observable_vector <T> **.Below is a listing of a class called single_threaded_observable_vector<T>. Sarà facile passare dal tipo seguente a WinRT:: single_threaded_observable_vector quando si usa una versione del Windows SDK che la contiene.It'll be easy to switch over from the type below to winrt::single_threaded_observable_vector when you're on a version of the Windows SDK that contains it.

// single_threaded_observable_vector.h
#pragma once

namespace winrt::Bookstore::implementation
{
    using namespace Windows::Foundation::Collections;

    template <typename T>
    struct single_threaded_observable_vector : implements<single_threaded_observable_vector<T>,
        IObservableVector<T>,
        IVector<T>,
        IVectorView<T>,
        IIterable<T>>
    {
        event_token VectorChanged(VectorChangedEventHandler<T> const& handler)
        {
            return m_changed.add(handler);
        }

        void VectorChanged(event_token const cookie)
        {
            m_changed.remove(cookie);
        }

        T GetAt(uint32_t const index) const
        {
            if (index >= m_values.size())
            {
                throw hresult_out_of_bounds();
            }

            return m_values[index];
        }

        uint32_t Size() const noexcept
        {
            return static_cast<uint32_t>(m_values.size());
        }

        IVectorView<T> GetView()
        {
            return *this;
        }

        bool IndexOf(T const& value, uint32_t& index) const noexcept
        {
            index = static_cast<uint32_t>(std::find(m_values.begin(), m_values.end(), value) - m_values.begin());
            return index < m_values.size();
        }

        void SetAt(uint32_t const index, T const& value)
        {
            if (index >= m_values.size())
            {
                throw hresult_out_of_bounds();
            }

            ++m_version;
            m_values[index] = value;
            m_changed(*this, make<args>(CollectionChange::ItemChanged, index));
        }

        void InsertAt(uint32_t const index, T const& value)
        {
            if (index > m_values.size())
            {
                throw hresult_out_of_bounds();
            }

            ++m_version;
            m_values.insert(m_values.begin() + index, value);
            m_changed(*this, make<args>(CollectionChange::ItemInserted, index));
        }

        void RemoveAt(uint32_t const index)
        {
            if (index >= m_values.size())
            {
                throw hresult_out_of_bounds();
            }

            ++m_version;
            m_values.erase(m_values.begin() + index);
            m_changed(*this, make<args>(CollectionChange::ItemRemoved, index));
        }

        void Append(T const& value)
        {
            ++m_version;
            m_values.push_back(value);
            m_changed(*this, make<args>(CollectionChange::ItemInserted, Size() - 1));
        }

        void RemoveAtEnd()
        {
            if (m_values.empty())
            {
                throw hresult_out_of_bounds();
            }

            ++m_version;
            m_values.pop_back();
            m_changed(*this, make<args>(CollectionChange::ItemRemoved, Size()));
        }

        void Clear() noexcept
        {
            ++m_version;
            m_values.clear();
            m_changed(*this, make<args>(CollectionChange::Reset, 0));
        }

        uint32_t GetMany(uint32_t const startIndex, array_view<T> values) const
        {
            if (startIndex >= m_values.size())
            {
                return 0;
            }

            uint32_t actual = static_cast<uint32_t>(m_values.size() - startIndex);

            if (actual > values.size())
            {
                actual = values.size();
            }

            std::copy_n(m_values.begin() + startIndex, actual, values.begin());
            return actual;
        }

        void ReplaceAll(array_view<T const> value)
        {
            ++m_version;
            m_values.assign(value.begin(), value.end());
            m_changed(*this, make<args>(CollectionChange::Reset, 0));
        }

        IIterator<T> First()
        {
            return make<iterator>(this);
        }

    private:

        std::vector<T> m_values;
        event<VectorChangedEventHandler<T>> m_changed;
        uint32_t m_version{};

        struct args : implements<args, IVectorChangedEventArgs>
        {
            args(CollectionChange const change, uint32_t const index) :
                m_change(change),
                m_index(index)
            {
            }

            CollectionChange CollectionChange() const
            {
                return m_change;
            }

            uint32_t Index() const
            {
                return m_index;
            }

        private:

            Windows::Foundation::Collections::CollectionChange const m_change{};
            uint32_t const m_index{};
        };

        struct iterator : implements<iterator, IIterator<T>>
        {
            explicit iterator(single_threaded_observable_vector<T>* owner) noexcept :
            m_version(owner->m_version),
                m_current(owner->m_values.begin()),
                m_end(owner->m_values.end())
            {
                m_owner.copy_from(owner);
            }

            void abi_enter() const
            {
                if (m_version != m_owner->m_version)
                {
                    throw hresult_changed_state();
                }
            }

            T Current() const
            {
                if (m_current == m_end)
                {
                    throw hresult_out_of_bounds();
                }

                return*m_current;
            }

            bool HasCurrent() const noexcept
            {
                return m_current != m_end;
            }

            bool MoveNext() noexcept
            {
                if (m_current != m_end)
                {
                    ++m_current;
                }

                return HasCurrent();
            }

            uint32_t GetMany(array_view<T> values)
            {
                uint32_t actual = static_cast<uint32_t>(std::distance(m_current, m_end));

                if (actual > values.size())
                {
                    actual = values.size();
                }

                std::copy_n(m_current, actual, values.begin());
                std::advance(m_current, actual);
                return actual;
            }

        private:

            com_ptr<single_threaded_observable_vector<T>> m_owner;
            uint32_t const m_version;
            typename std::vector<T>::const_iterator m_current;
            typename std::vector<T>::const_iterator const m_end;
        };
    };
}

La funzione Append illustra come generare l'evento IObservableVector < T > :: VectorChanged .The Append function illustrates how to raise the IObservableVector<T>::VectorChanged event.

m_changed(*this, make<args>(CollectionChange::ItemInserted, Size() - 1));

Gli argomenti dell'evento indicano che è stato inserito un elemento e anche il relativo indice (l'ultimo elemento, in questo caso).The event arguments indicate both that an element was inserted, and also what its index is (the last element, in this case). Questi argomenti consentono a un controllo elementi XAML di rispondere all'evento e di aggiornarsi in modo ottimale.These arguments enable a XAML items control to respond to the event and to refresh itself in the optimal way.

Questo è il modo in cui si crea un'istanza del tipo definito sopra.This is how you'd create an instance of the type defined above. Anziché chiamare il modello di funzione WinRT:: single_threaded_observable_vector Factory, è necessario creare l'oggetto raccolta chiamando WinRT:: make.Instead of calling the winrt::single_threaded_observable_vector factory function template, you create the collection object by calling winrt::make.

#include "single_threaded_observable_vector.h"
...
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable> m_bookSkus;
...
m_bookSkus = winrt::make<winrt::Bookstore::implementation::single_threaded_observable_vector<winrt::Windows::Foundation::IInspectable>>();

Vedere ancheSee also