// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once namespace CalculatorApp { namespace Common { ref class AlwaysSelectedCollectionView sealed : public Windows::UI::Xaml::DependencyObject, public Windows::UI::Xaml::Data::ICollectionView { internal : AlwaysSelectedCollectionView(Windows::UI::Xaml::Interop::IBindableVector ^ source) : m_currentPosition(-1) { m_source = source; Windows::UI::Xaml::Interop::IBindableObservableVector ^ observable = dynamic_cast(source); if (observable) { observable->VectorChanged += ref new Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler( this, &AlwaysSelectedCollectionView::OnSourceBindableVectorChanged); } } private: // ICollectionView // Not implemented methods virtual Windows::Foundation::IAsyncOperation< Windows::UI::Xaml::Data::LoadMoreItemsResult> ^ LoadMoreItemsAsync(unsigned int) = Windows::UI::Xaml::Data::ICollectionView::LoadMoreItemsAsync { throw ref new Platform::NotImplementedException(); } virtual bool MoveCurrentToFirst() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToFirst { throw ref new Platform::NotImplementedException(); } virtual bool MoveCurrentToLast() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToLast { throw ref new Platform::NotImplementedException(); } virtual bool MoveCurrentToNext() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToNext { throw ref new Platform::NotImplementedException(); } virtual bool MoveCurrentToPrevious() = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPrevious { throw ref new Platform::NotImplementedException(); } property Windows::Foundation::Collections::IObservableVector ^ CollectionGroups { virtual Windows::Foundation::Collections::IObservableVector< Platform::Object ^> ^ get() = Windows::UI::Xaml::Data::ICollectionView::CollectionGroups::get { return ref new Platform::Collections::Vector(); } } property bool HasMoreItems { virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::HasMoreItems::get { return false; } } // Implementented methods virtual bool MoveCurrentTo(Platform::Object ^ item) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentTo { if (item) { unsigned int newCurrentPosition = 0; bool result = m_source->IndexOf(item, &newCurrentPosition); if (result) { m_currentPosition = newCurrentPosition; m_currentChanged(this, nullptr); return true; } } // The item is not in the collection // We're going to schedule a call back later so we // restore the selection to the way we wanted it to begin with if (m_currentPosition >= 0 && m_currentPosition < static_cast(m_source->Size)) { this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() { m_currentChanged(this, nullptr); })); } return false; } virtual bool MoveCurrentToPosition(int index) = Windows::UI::Xaml::Data::ICollectionView::MoveCurrentToPosition { if (index < 0 || index >= static_cast(m_source->Size)) { return false; } m_currentPosition = index; m_currentChanged(this, nullptr); return true; } property Platform::Object^ CurrentItem { virtual Platform::Object^ get() = Windows::UI::Xaml::Data::ICollectionView::CurrentItem::get { if (m_currentPosition >= 0 && m_currentPosition < static_cast(m_source->Size)) { return m_source->GetAt(m_currentPosition); } return nullptr; } } property int CurrentPosition { virtual int get() = Windows::UI::Xaml::Data::ICollectionView::CurrentPosition::get { return m_currentPosition; } } property bool IsCurrentAfterLast { virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentAfterLast::get { return m_currentPosition >= static_cast(m_source->Size); } } property bool IsCurrentBeforeFirst { virtual bool get() = Windows::UI::Xaml::Data::ICollectionView::IsCurrentBeforeFirst::get { return m_currentPosition < 0; } } event Windows::Foundation::EventHandler^ CurrentChanged { virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::EventHandler^ handler) = Windows::UI::Xaml::Data::ICollectionView::CurrentChanged::add { return m_currentChanged += handler; } virtual void remove(Windows::Foundation::EventRegistrationToken token) = Windows::UI::Xaml::Data::ICollectionView::CurrentChanged::remove { m_currentChanged -= token; } } event Windows::UI::Xaml::Data::CurrentChangingEventHandler^ CurrentChanging { virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Data::CurrentChangingEventHandler^ handler) = Windows::UI::Xaml::Data::ICollectionView::CurrentChanging::add { return m_currentChanging += handler; } virtual void remove(Windows::Foundation::EventRegistrationToken token) = Windows::UI::Xaml::Data::ICollectionView::CurrentChanging::remove { m_currentChanging -= token; } } // IVector // Not implemented methods virtual void Append(Platform::Object^ /*item*/) = Windows::Foundation::Collections::IVector::Append { throw ref new Platform::NotImplementedException(); } virtual void Clear() = Windows::Foundation::Collections::IVector::Clear { throw ref new Platform::NotImplementedException(); } virtual unsigned int GetMany( unsigned int /*startIndex*/, Platform::WriteOnlyArray ^ /*items*/) = Windows::Foundation::Collections::IVector::GetMany { throw ref new Platform::NotImplementedException(); } virtual Windows::Foundation::Collections::IVectorView ^ GetView() = Windows::Foundation::Collections::IVector< Platform::Object ^>::GetView { throw ref new Platform::NotImplementedException(); } virtual void InsertAt(unsigned int /*index*/, Platform::Object ^ /*item*/) = Windows::Foundation::Collections::IVector::InsertAt { throw ref new Platform::NotImplementedException(); } virtual void RemoveAt(unsigned int /*index*/) = Windows::Foundation::Collections::IVector::RemoveAt { throw ref new Platform::NotImplementedException(); } virtual void RemoveAtEnd() = Windows::Foundation::Collections::IVector::RemoveAtEnd { throw ref new Platform::NotImplementedException(); } virtual void ReplaceAll(const Platform::Array ^ /*items*/) = Windows::Foundation::Collections::IVector::ReplaceAll { throw ref new Platform::NotImplementedException(); } virtual void SetAt(unsigned int /*index*/, Platform::Object ^ /*item*/) = Windows::Foundation::Collections::IVector::SetAt { throw ref new Platform::NotImplementedException(); } // Implemented methods virtual Platform::Object ^ GetAt(unsigned int index) = Windows::Foundation::Collections::IVector::GetAt { return m_source->GetAt(index); } virtual bool IndexOf(Platform::Object ^ item, unsigned int* index) = Windows::Foundation::Collections::IVector::IndexOf { return m_source->IndexOf(item, index); } property unsigned int Size { virtual unsigned int get() = Windows::Foundation::Collections::IVector::Size::get { return m_source->Size; } } // IObservableVector event Windows::Foundation::Collections::VectorChangedEventHandler^ VectorChanged { virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::Collections::VectorChangedEventHandler^ handler) = Windows::Foundation::Collections::IObservableVector::VectorChanged::add { return m_vectorChanged += handler; } virtual void remove(Windows::Foundation::EventRegistrationToken token) = Windows::Foundation::Collections::IObservableVector::VectorChanged::remove { m_vectorChanged -= token; } } // IIterable // Not implemented virtual Windows::Foundation::Collections::IIterator^ First() = Windows::Foundation::Collections::IIterable::First { throw ref new Platform::NotImplementedException(); } // Event handlers void OnSourceBindableVectorChanged(Windows::UI::Xaml::Interop::IBindableObservableVector ^ source, Platform::Object ^ e) { Windows::Foundation::Collections::IVectorChangedEventArgs ^ args = safe_cast(e); m_vectorChanged(this, args); } Windows::UI::Xaml::Interop::IBindableVector ^ m_source; int m_currentPosition; event Windows::Foundation::EventHandler ^ m_currentChanged; event Windows::UI::Xaml::Data::CurrentChangingEventHandler ^ m_currentChanging; event Windows::Foundation::Collections::VectorChangedEventHandler ^ m_vectorChanged; }; public ref class AlwaysSelectedCollectionViewConverter sealed : public Windows::UI::Xaml::Data::IValueConverter { public: AlwaysSelectedCollectionViewConverter() { } private: virtual Platform::Object ^ Convert( Platform::Object ^ value, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/, Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::Convert { auto result = dynamic_cast(value); if (result) { return ref new AlwaysSelectedCollectionView(result); } return Windows::UI::Xaml::DependencyProperty::UnsetValue; // Can't convert } virtual Platform::Object ^ ConvertBack( Platform::Object ^ /*value*/, Windows::UI::Xaml::Interop::TypeName /*targetType*/, Platform::Object ^ /*parameter*/, Platform::String ^ /*language*/) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack { return Windows::UI::Xaml::DependencyProperty::UnsetValue; } }; } }