Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在windows应用商店应用程序中强制重画ListView_Listview_Windows Store Apps_C++ Cx - Fatal编程技术网

在windows应用商店应用程序中强制重画ListView

在windows应用商店应用程序中强制重画ListView,listview,windows-store-apps,c++-cx,Listview,Windows Store Apps,C++ Cx,我正在使用@Romasz的回答为ListView项目提供备用背景。我更改它以突出显示所选项目,如下所示: <local:AlternateConverter CurrentList="{Binding ElementName=myList, Path=ItemsSource}" HighlightIndex="{Binding ElementName=myList, Path=SelectedIndex}"

我正在使用@Romasz的回答为
ListView
项目提供备用背景。我更改它以突出显示所选项目,如下所示:

<local:AlternateConverter CurrentList="{Binding ElementName=myList, Path=ItemsSource}" 
                          HighlightIndex="{Binding ElementName=myList, Path=SelectedIndex}"
                          x:Key="AlternateConverter"/>
问题是,正如您可能从标题中猜到的那样,
ListView
中某个项目的背景不会在我选择它时重新呈现。根据我的经验,这会触发一个事实,即我没有处理在进行选择时触发的事件。所以我补充说

    <ListView x:Name="myList" SelectionChanged="OnItemSelected">
           <!-- Omitted code -->
    </ListView>
现在,新的问题是列表视图在每次选择后都会闪烁,并且列表的查看状态完全丢失(例如,列表会自动回滚到列表的开头)


因此,我想寻求一种正确的方法来强制
列表视图
(或任何其他UI元素)重新绘制自身。

结果是
列表视图
使用为每个“逻辑”(非UI信息)项提供的数据模板创建
列表视图项
。方法
ListView::ContainerFromIndex
ListView::ContainerFromItem
允许从给定索引或逻辑项访问
ListViewItem
。然后,我们可以操纵属性
ListViewItem::ContentTemplateRoot
,以实现我们需要的功能

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;
    }
}
void主页::OnSelectionChanged(平台::对象^sender,Windows::UI::Xaml::控件::SelectionChangedEventArgs ^e)
{
自动列表视图=(列表视图^)发送方;
//还原未选定项目的背景
自动列表=重新解释转换(listview->ItemsSource);
用于(自动项目:e->RemovedItems)
{
无符号整数索引;
列表->索引(项目和索引);
自动容器=(ListViewItem^)listview->ContainerFromIndex(索引);
自动边框=(边框^)容器->ContentTemplateRoot;
边框->背景=索引%2==0?刷偶数:刷奇数;
//此空检查是必要的,因为当[unselected]项退出视图时,ListView似乎重用ListViewItem来显示其他项,并简单地返回nullptr。
if(容器!=nullptr)
{
自动边框=(边框^)容器->ContentTemplateRoot;
边框->背景=DefaultBrushTransparent;
}
}
//突出显示所选项目
用于(自动项目:e->AddedItems)
{
自动容器=(ListViewItem^)listview->ContainerFromItem(项目);
自动边框=(边框^)容器->ContentTemplateRoot;
边框->背景=BrushHighlight;
}
}
这个解决方案并不完美。如果选择一个项目并向下滚动列表,使所选项目不在视图中,然后选择一个新项目,则未选中项目的背景不会恢复到正常状态,因此当一个项目向上移动时,该项目显示为选中


最好的,即完全工作的解决方案来自Romasz的评论,尽管将UI集成到模型设计中并不理想。

我有两个快速的想法:1。在您的项目中定义一个属性,该属性将负责背景颜色,它甚至可以与SPROPRATE CONVERTOR一起使用,2。选择更改后,不要更改itemtemplate,只更改取消选择的项目的颜色-我认为这也可以在xaml中完成。
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;
}
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;
    }
}