2

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

我为 ItemsSource 创建了一个 DependencyProperty 来模仿内置 ItemsControl 的(抽象父级到其他列表)。ItemsControl 将 ItemsSource 定义为Platform::Object^,所以我也这样做了。这工作正常。

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

使用现有容器(例如 ListView),您可以将 ItemsSource 设置为 aVector<MyCustomViewModel^>^而无需先将其转换为 aVector<Object^>^并且它工作得很好。那么他们是怎么做到的呢?他们不使用safe_cast吗?我很确定在这里使用不太安全的演员表会产生不利影响。还有其他想法吗?

TL;博士:

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

4

1 回答 1

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^>)。

于 2012-12-06T01:44:10.033 回答