从C++/Cx中的框架对象转换为模板化类

Bre*_*aut 2 windows casting visual-c++ windows-runtime c++-cx

我正在努力在WinRT项目中创建一个新容器.此容器的行为类似于ListView,因此我决定在其属性中使用类似的名称.

我为ItemsSource创建了一个DependencyProperty来模仿内置的ItemsControl(其他列表的抽象父).ItemsControl将ItemsSource定义为a Platform::Object^,所以我做了同样的事情.这很好用.

稍后,是时候创建要进入列表的项目,使用指定的ItemsTemplate实例填充它们,并设置它们的数据上下文.这意味着我需要实际将ItemsSource Platform::Object^转换为可迭代的东西.不幸的是,要将其转换为可迭代的东西,我需要在强制转换中指定模板化类型(例如IIterable<UIElement^>^IIterable<Object^>^).在这个阶段,我并不特别关心它是什么类型的对象,因为我只是将它用作新列表项的DataContext,所以转换为没问题IIterable<Object^>^.不幸的是,safe_cast不允许我这样做,除非最初设置为ItemsSource的东西也被模板化为某个IIterable<Object^>^或某个孩子,例如IVectorView<Object^>^.

使用ListView等现有容器,您可以将ItemsSource设置为a Vector<MyCustomViewModel^>^而不先将其转换为a Vector<Object^>^并且它可以正常工作.那他们怎么做呢?他们没有使用safe_cast吗?我很确定使用不太安全的演员阵容会产生不利影响.还有其他想法吗?

TL; DR:

我有一些Platform::Object^参考,我知道指向其他参考的IIterable.是否有可能以IIterable<Platform::Object^>^某种方式将其强制转换,即使迭代最初是使用其他模板创建的(例如IIterable<MyCustomViewModel^>^)?

And*_*ich 5

由于C++/CX不支持类型协变/反演(Platform::Vector<T^>未实现IVector<Object^>),因此Xaml团队添加了一个特殊的非泛型接口Windows.UI.Xaml.Interop.IBindableObservableVector,它为您提供了一个基于对象的集合来进行迭代.Platform :: Vector专门实现此接口以处理您正在努力解决的问题.因此,在您的情况下,您应该能够转换并使用此特殊界面.

我不确定.NET集合是否支持此接口,因此对于支持C#/ VB的自定义控件,您可能希望对IBindableObservableVector执行dynamic_cast,如果结果为nullptr,则尝试转换为其他集合类型(例如IVector<Object^>).

  • 具体来说,IBindableVector接口(IBOV继承)具有您正在寻找的大部分功能. (2认同)