我很难用C++/WinRT将IObservableMap绑定到ListView。我的MainPage.xaml看起来是这样的:
<ListView ItemsSource="{x:Bind TestCollection}">
</ListView>
其中TestCollection
是一个具有签名winrt::Windows::Foundation::Collections::IObservableMap<hstring, hstring> TestCollection()
的方法。
但是,当运行应用程序时,当使用ItemsSource
将TestCollection
属性设置为HRESULT: 0x80070057 (E_INVALIDARG)
时,它会在XAML设置代码中崩溃,这并不能真正告诉我多少,只是它不喜欢将映射作为参数。
我已经就这个问题咨询了文档,并向MS 这里提出了一个问题,因为它们是相互矛盾的。概括地说:
ItemsSource属性文档说:
The ItemsSource property value must implement one of these interfaces:
IIterable<IInspectable>
IBindableIterable
首先,IObservableMap实际上是根据C++/WinRT头实现的,而C++/WinRT文档则说:
If you want to bind a XAML items control to your collection, then you can.
But be aware that to correctly set the ItemsControl.ItemsSource property, you need to set it to a value of type IVector of IInspectable (or of an interoperability type such as IBindableObservableVector).
当用IObservableMap替换IObservableVector时,一切都如预期的那样工作。
我还试着用一本(不可观察的)字典在C#中做同样的事情,它工作得很好,这让我有点困惑。CLR是如何做到这一点的?它是否在某个地方将字典转换为IVector?它不适用于IMap中的C++,所以必须进行某种类型的转换,对吗?
编辑:在浪费大量时间和程序集级调试到Windows.UI.Xaml.dll
之后,我发现了以下情况:
IIterable<IInspectable>
执行QueryInterface
IIterable<IKeyValuePair<K,V>>
,这是一个IInspectable
,并不意味着您实现了IIterable<IInspectable>
有什么办法能让这件事成功吗?
我曾经考虑过做一个自定义集合,但这意味着我需要实现IIterable<IKeyValuePair<K,V>>
和IIterable<IInspectable>
,我尝试了一会儿,但这使编译器感到困惑,因为它有两个First()
方法,它不知道选择哪个方法,而我不知道该做什么。
同样,CLR是如何解决这一问题的?
发布于 2019-11-14 15:47:45
字典工作得很好,这让我有点困惑。CLR是如何做到这一点的?
在C# Dictionary<TKey,TValue>
实施器 IEnumerable<KeyValuePair<TKey,TValue>>
中
对于C++/CX,有平台::集合::地图,这个集合还实现了所有必要的接口。
对于C++/WinRT,有基础结构。它还实现了所有必要的接口。
文档中的示例实现:
...
#include <iostream>
using namespace winrt;
using namespace Windows::Foundation::Collections;
...
struct MyObservableMap :
implements<MyObservableMap, IObservableMap<winrt::hstring, int>, IMap<winrt::hstring, int>, IMapView<winrt::hstring, int>, IIterable<IKeyValuePair<winrt::hstring, int>>>,
winrt::observable_map_base<MyObservableMap, winrt::hstring, int>
{
auto& get_container() const noexcept
{
return m_values;
}
auto& get_container() noexcept
{
return m_values;
}
private:
std::map<winrt::hstring, int> m_values{
{ L"AliceBlue", 0xfff0f8ff }, { L"AntiqueWhite", 0xfffaebd7 }
};
};
IObservableMap<winrt::hstring, int> map{ winrt::make<MyObservableMap>() };
for (auto const& el : map)
{
std::wcout << el.Key().c_str() << L", " << std::hex << el.Value() << std::endl;
}
IIterator<IKeyValuePair<winrt::hstring, int>> it{ map.First() };
while (it.HasCurrent())
{
std::wcout << it.Current().Key().c_str() << L", " << std::hex << it.Current().Value() << std::endl;
it.MoveNext();
}
https://stackoverflow.com/questions/58816784
复制相似问题