【问题标题】:Casting to templated classes from framework objects in C++/Cx从 C++/Cx 中的框架对象转换为模板类
【发布时间】:2012-11-22 16:35:26
【问题描述】:

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

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

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

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

TL;DR:

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

【问题讨论】:

    标签: windows visual-c++ casting windows-runtime c++-cx


    【解决方案1】:

    由于 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 继承自)具有您正在寻找的大部分功能。
    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 2020-11-27
    • 2015-10-25
    • 1970-01-01
    • 2014-04-28
    • 2016-04-05
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多