将IObservableMap绑定到ItemsControl(例如ListView)

我在使用C ++ / WinRT将IObservableMap绑定到ListView时遇到麻烦。我的MainPage.xaml看起来像这样:

<ListView ItemsSource="{x:Bind TestCollection}">
</ListView>

其中TestCollection是签名为winrt::Windows::Foundation::Collections::IObservableMap<hstring,hstring> TestCollection()的方法。

但是,在运行应用程序时,将ItemsSource的{​​{1}}属性设置为TestCollection时,它会在XAML设置代码中崩溃,这并没有告诉我很多,除了它没有不喜欢将地图作为参数。

我已就此问题咨询过文档,并提出了有关MS文档here的问题,因为它们相互矛盾。总结一下:

ItemsSource属性文档说:

HRESULT: 0x80070057 (E_INVALIDARG)

首先,IObservableMap实际上根据C ++ / WinRT标头实现,而C ++ / WinRT文档说:

The ItemsSource property value must implement one of these interfaces:
IIterable<IInspectable>
IBindableIterable

将IObservableMap替换为IObservableVector时,一切正常。
我还尝试使用(不可观察的)Dictionary在C#中做等效的事情,并且效果很好,这让我有些困惑。 CLR如何做到这一点?是否将Dictionary转换为IVector?它不适用于C ++中的IMap,因此必须进行某种转换,对吧?

编辑:在浪费大量时间并在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). 进行汇编级调试之后,我发现了以下内容:

  • ItemsSource方法的实现为Windows.UI.Xaml.dllQueryInterface
  • 参数化接口的IID是generated,基于插入的类型参数
  • 即使您实现的IIterable<IInspectable>IIterable<Ikeyvaluepair<K,V>>,也不意味着您实现了IInspectable
  • 我的头很痛

有没有办法使这项工作奏效?
我曾考虑过要创建一个自定义集合,但这意味着我需要同时实现IIterable<IInspectable>IIterable<Ikeyvaluepair<K,V>>,这已经尝试了一段时间,但是由于有两个{ {1}}方法,它不知道该选哪个,而我也不知道该怎么做。
同样,CLR如何解决这个问题?

abxtoo 回答:将IObservableMap绑定到ItemsControl(例如ListView)

  

字典,它工作得很好,这让我有些困惑。 CLR如何做到这一点?

在C#Dictionary<TKey,TValue> implements IEnumerable<KeyValuePair<TKey,TValue>>

对于C ++ / CX,有Platform::Collections::Map这个集合还实现了所有必要的接口。

对于C ++ / WinRT,有winrt::observable_map_base struct。这也实现了所有必要的接口。

文档中的示例实现

...
#include <iostream>
using namespace winrt;
using namespace Windows::Foundation::Collections;
...
struct MyObservableMap :
    implements<MyObservableMap,IObservableMap<winrt::hstring,int>,IMap<winrt::hstring,IMapView<winrt::hstring,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://www.f2er.com/3118208.html

大家都在问