Aracılığıyla paylaş


winrt::single_threaded_observable_vector işlev şablonu (C++/WinRT)

Gözlemlenebilir bir koleksiyon uygulayan türde bir nesne oluşturan ve döndüren işlev şablonu. nesnesi bir IObservableVector olarak döndürülür ve döndürülen nesnenin işlevlerini ve özelliklerini çağırdığınız arabirimdir.

İsteğe bağlı olarak var olan bir std::vectorrvalue dosyasını işleve geçirebilirsiniz; geçici bir nesne geçirebilir veya lvalue üzerinde std::move çağrısı yapabilirsiniz.

Daha fazla bilgi ve kod örnekleri için bkz. C++/WinRT ile Koleksiyonlar.

Sözdizimi

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

Şablon parametreleri

typename T Koleksiyonun öğelerinin türü.

typename Allocator Koleksiyonun başlatıldığı vektörün ayırıcısının türü, bir tane geçirirseniz, aksi takdirde varsayılan ayırıcı.

Parametreler

valuesKoleksiyon nesnesinin öğelerinin başlatıldığı std::vector türünde bir rvalue'ya isteğe bağlı başvuru.

Dönüş değeri

Yeni bir koleksiyon nesnesini temsil eden bir IObservableVector .

Gereksinimler

Desteklenen en düşük SDK: Windows SDK sürüm 10.0.17763.0 (Windows 10, sürüm 1809)

Ad alanı: winrt

Üst bilgi: %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt\Windows.Foundation.Collections.h

Windows SDK'sının daha eski bir sürümüne sahipseniz

Windows SDK sürüm 10.0.17763.0 (Windows 10, sürüm 1809) veya sonraki bir sürümüne sahip değilseniz , IObservableVector<T'nin> kullanışlı, genel amaçlı bir uygulaması olarak hizmet vermek için kendi gözlemlenebilir vektör şablonunuzu uygulamanız gerekir. Aşağıda single_threaded_observable_vector T adlı sınıfın listesi yer almaktadır>.< Aşağıdaki türden winrt::single_threaded_observable_vector içeren bir Windows SDK sürümündeyken geçiş yapmak kolay olacaktır.

// 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;
        };
    };
}

Append işlevi, IObservableVector<T>::VectorChanged olayının nasıl yükseltilmesine ilişkin bir resim gösterir.

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

Olay bağımsız değişkenleri hem bir öğenin eklendiğini hem de dizinin ne olduğunu gösterir (bu örnekte son öğe). Bu bağımsız değişkenler, bir XAML öğeleri denetiminin olaya yanıt vermesini ve kendisini en uygun şekilde yenilemesini sağlar.

Yukarıda tanımlanan türün bir örneğini bu şekilde oluşturursunuz. winrt::single_threaded_observable_vector factory işlev şablonunu çağırmak yerine winrt::make öğesini çağırarak koleksiyon nesnesini oluşturursunuz.

#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>>();

Ayrıca bakınız