以编程方式为ListView的项目构建UI

时间:2017-07-12 09:52:30

标签: c++ uwp

从各种问题来看,我知道在不使用DataTemplate的情况下,无法从后面的代码中创建XamlReader。所以我想问一下是否有办法以编程方式为ListView中的每个项目生成UI。我似乎没有为此找到任何相关的事件处理程序或ListView的成员。理想情况下,我希望ListView调用我的处理程序代码来为它需要显示的每个数据项生成UI。

2 个答案:

答案 0 :(得分:1)

模仿官方XamlTreeView示例,我尝试覆盖某些ListView方法,例如PrepareContainerForItemOverride,但这不起作用。我发现的解决方案是@JustinXL建议:生成ListViewItem并将它们直接插入ListView->Items

//assume that items is a list of items we want to bind
myListView->Items->Clear();
for(auto i : items)
{
     ListViewItem^ v = ref new ListViewItem();
     v->Content = GenerateUIFor(i);
     myListView->Items->Append(v); // NOTE: a wrapping ListViewItem is required!
}

为了支持通常的数据绑定,最好使数据结构缓存生成的UI。例如,

ref class MyDataStructure
{
public:
    property ListViewItem^ Item
    {
        ListViewItem^ get()
        {
             if (_item == nullptr)
                 GenerateUI();
             return _item;
        }
    }
    void GenerateUI()
    {
        _item = ref new ListViewItem();
        _text_block = ref new TextBlock(); // sample
        _item->Content = _text_block;
        UpdateUI();
    }

    // Invoke this when changing the state of this object
    void UpdateUI()
    {
        if (_text_block != nullptr) // sample
        {
             _text_block->Text = this->ToString(); // sample
        }
    }
private:
    ListViewItem^ _item;
    TextBlock^ _text_block;
};

这样做的缺点当然是我们无法利用数据虚拟化。但它适用于少量数据。对于大型集合,可以使用网站的方法使用下一步上一页按钮来加载下一页或返回上一页。

答案 1 :(得分:0)

ItemContainerGenerator应该让您为列表视图中的项目构建整个UI。遗憾的是,对于非MSDN文档/样本而言,似乎没有太大的障碍。

或者,如果您可以维护可能需要显示的所有DataTemplates的列表,则可以使用DataTemplateSelector选择要为每个项目显示的DataTemplate。