队的ListView重绘在Windows商店应用 [英] Force redraw on ListView in windows store app

查看:165
本文介绍了队的ListView重绘在Windows商店应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用@Romasz的回答从<一个href=\"http://stackoverflow.com/questions/27607886/alternating-colors-of-rows-in-listview-in-windows-phone-8-1\">Alternating在Windows Phone的8.1 ​​ ListView中的行颜色给备用背景的ListView 项目。我改变它以高亮显示所选项目,像这样的:

I am using @Romasz 's answer from Alternating Colors of rows in ListView in Windows Phone 8.1 to give alternate background to ListView items. I change it in order to highlight the selected item, like this:

<local:AlternateConverter CurrentList="{Binding ElementName=myList, Path=ItemsSource}" 
                          HighlightIndex="{Binding ElementName=myList, Path=SelectedIndex}"
                          x:Key="AlternateConverter"/>

请注意:我删除了 AlternateBrushes 属性,因为我只需要静态的色彩,并添加 HighlightItem 属性绑定到名单的选定的索引。

Note: I removed the AlternateBrushes property as I only need static colors and add in HighlightItem property binding to the list's selected index.

然后,我改变了转换器类 AlternateConverter 适当如下:[注:这是C ++的对应]

Then I changed the converter class AlternateConverter appropriately as follow: [NB: this is C++ counterpart.]

Object^ AlternateConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
    auto list = reinterpret_cast<IVector<Object^>^>(CurrentList);
    unsigned int i;
    bool r = list->IndexOf(value, &i);

    // This is added to highlight the selected item with a different color
    if (i == HighlightIndex)
        return BrushHighlight;

    return i % 2 == 0 ? BrushEven : BrushOdd;
}

问题是,你可能从标题时,我选择它猜想,在的ListView 一个项目的背景是不是重新呈现。根据我的经验,这会触发事实上,我做出选择的时候没有处理事件被解雇。所以我加了

The problem is, as you might guess from the title, the background for an item in the ListView is not re-rendered whenever I select it. In my experience, this triggers the fact that I did not handle event fired when the selection is made. So I added

    <ListView x:Name="myList" SelectionChanged="OnItemSelected">
           <!-- Omitted code -->
    </ListView>

不幸的是,在API中没有地方告诉我如何的正常的重绘的ListView 。我能得到最接近的是这种愚蠢code:

Unfortunately, there is no place in the API telling me how to properly redraw the ListView. The closest thing I could get is by this stupid code:

void MainPage::OnItemSelected(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
    // This is to trigger OnItemTemplateChanged which have a side effect of redrawing the whole list view.
    myList->ItemTemplate = myList->ItemTemplate;
}

现在,新的问题是,列表视图每个选择后闪烁和列表的查看状态是完全丧失(如列表会自动滚动回到列表的开头)。

Now, the new problem is that the list view flickers after every selection and the viewing state of the list is totally lost (e.g. the list automatically scrolls back to the beginning of the list).

所以我要问的正确方法来强制的ListView (或任何其他UI元素)重绘自身。

So I want to ask for the proper way to force a ListView (or any other UI element) to redraw itself.

推荐答案

原来,的ListView 创建 ListViewItem的使用每个逻辑(非UI信息)项所提供的数据模板。该方法的ListView :: ContainerFromIndex 的ListView :: ContainerFromItem 允许人们访问 ListViewItem的从给定的索引或者从逻辑的项目。然后,我们可以操纵属性的ListViewItem :: ContentTemplateRoot 来实现我们所需要的。

It turns out that ListView create ListViewItem using the supplied data template for each "logical" (non-UI information) item. The methods ListView::ContainerFromIndex and ListView::ContainerFromItem allows one to access the ListViewItem from a given index or from the logical item. Then we can manipulate the property ListViewItem::ContentTemplateRoot to achieve what we need.

void MainPage::OnSelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
    auto listview = (ListView^)sender;

    // Restore background for unselected item
    auto list = reinterpret_cast<IVector<Object^>^>(listview->ItemsSource);
    for (auto item : e->RemovedItems)
    {
        unsigned int index;
        list->IndexOf(item, &index);
        auto container = (ListViewItem^)listview->ContainerFromIndex(index);

        auto border = (Border^)container->ContentTemplateRoot;
        border->Background = index % 2 == 0 ? BrushEven : BrushOdd;

        // This null check is necessary because when the [unselected] item goes out of view, ListView seems to reuse the ListViewItem to display other item and simply return nullptr.
        if (container != nullptr)
        {
            auto border = (Border^)container->ContentTemplateRoot;
            border->Background = DefaultBrushTransparent;
        }
    }

    // Highlight the selected item
    for (auto item : e->AddedItems)
    {
        auto container = (ListViewItem^)listview->ContainerFromItem(item);
        auto border = (Border^)container->ContentTemplateRoot;
        border->Background = BrushHighlight;
    }
}

这方案并不完美。如果一个人选择一个项目,因此所选择的产品拿出来看长期向下滚动列表,然后选择一个新的项目,未选择的背景不会恢复到正常状态,所以当一个人nagivates向上,该项目显示为选中! ?

This solution is not perfect. If one selects an item and scroll long down the list so that the selected item is out of view and then select a new item, the background of the unselected is not restored to normal state, so when one nagivates upward, the item appears selected!?

最好的,即完全工作的解决方案来源于尽管这种整合-的-UI-到模型设计Romasz的评论不太理想。

The best i.e. fully working solution comes from Romasz's comment though such integration-of-UI-into-model design is less than ideal.

这篇关于队的ListView重绘在Windows商店应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆