在 Windows 8.1 GridView 中不显示 Visibility=Collapsed 的项目

Posted

技术标签:

【中文标题】在 Windows 8.1 GridView 中不显示 Visibility=Collapsed 的项目【英文标题】:Not showing items with Visibility=Collapsed in Windows 8.1 GridView 【发布时间】:2015-01-30 12:43:58 【问题描述】:

我有一个 Windows 8.1 应用程序,其 GridView 绑定到自定义(可排序、去重)可观察集合。在这个集合中,我做了一些重过滤并为每个项目设置一个 IsHidden 标志。

在项目的数据模板中,如果 IsHidden 标志设置为 true,则存在使项目折叠的条件。

<Grid Width="160" Height="280" Visibility="Binding IsHidden, Converter=StaticResource InvertedBooleanToVisibilityConverter">

此方法在 Windows Phone 8.1 XAML 中有效,使项目从 ListView 中消失,但在 Windows 8.1 GridView 中无效。 Windows 8.1 的问题是,当我将集合中的一个项目设置为隐藏时,id 从GridView 中消失但留下一个空白的地方,因此GridView 中有一个间隙。

关于如何解决它的任何想法?可能是相同的 XAML 样式编辑?

这是重现问题的最小解决方案:https://dl.dropboxusercontent.com/u/73642/gv.zip

我尝试将项目的宽度和高度绑定到隐藏标志,并在项目隐藏时将其设置为 0,但没有帮助,GridView 中仍然存在差距。

更新:一种解决方法是过滤实际绑定的集合,但由于某些业务需求,这是不可能的。

【问题讨论】:

你确定是Visibility.Collapsed?因为它看起来像Visibility.Hidden(你肯定知道difference)。 是的,我确定,winrt中没有Visibility.Hidden 您使用什么作为 GridView.ItemsPanel? 【参考方案1】:

问题出在GridViewItemsPanel

ItemsWrapGridWrapGrid 都是统一网格。他们所有的子元素将共享相同的高度和宽度。这就是为什么即使你折叠ItemTemplate,空间仍然被保留。

您真正需要的是WrapPanel。 WINRT 没有内置的 WrapPanel,但 Jerry Nixon 已经构建了一个,您可以从 here 获取它。

更新您的GridViews ItemsPanel 后,您还有一件事要做。您还需要获取托管您的ItemtemplateGridViewItem 并将其Visibility 设置为Collapsed

    private async void Button_Click(object sender, RoutedEventArgs e)
    
        ds[5].IsHidden = true;
  
        await Task.Delay(1000);
        var gridViewItem =(GridViewItem)this.gv.ContainerFromIndex(5);
        gridViewItem.Visibility = Visibility.Collapsed;
    

我在上面放了一点延迟,让崩溃更明显。

【讨论】:

感谢您对WrapPanel 的信任。你很好地解释了这个问题。在我看来,从ObservableCollection&lt;T&gt; 中删除它会给他所有他想要的一切,而不需要所有的编码体操;但是,我看到了他的评论。 你值得称赞@JerryNixon-MSFT,否则我什至无法回答! :)【参考方案2】:

我花了很多时间来理解问题以及眼前的解决方案。您试图隐藏项目本身但容器仍然存在,当您将项目添加到 GridView 时,该项目被包装在项目容器中。来自msdn:

" 当您将项目添加到 ItemsControl 时,该项目被包装在一个 物品容器。例如,添加到 ListView 的项目被包装在 一个列表视图项。如果没有 UI 虚拟化,则保留整个数据集 在内存中,还会为每个项目创建一个项目容器 数据集。绑定到 1000 个项目的集合的 ListView 将 还创建 1000 个存储在内存中的 ListViewItem 容器。”

您需要禁用容器并创建两个 DataTemplate 并使用 DataTemplateSelector 您可以选择哪个 DataTemplate 用于禁用和活动项目。 Check this useful article 。

【讨论】:

【参考方案3】:

我尝试了您的示例解决方案并将其更改为 ListView。当网格本身被隐藏时,它表现出相同的行为。我没有要验证的 XAML Spy,但似乎任何基于列表的控件都会为列表中的每个项目分配一个呈现的项目。

我将您的点击处理程序更改为 ds.RemoveAt(5); 而不是隐藏该项目,并且该元素从视图中移除并带有漂亮的动画。这似乎符合预期,并且是一个有趣的发现。

【讨论】:

以上是关于在 Windows 8.1 GridView 中不显示 Visibility=Collapsed 的项目的主要内容,如果未能解决你的问题,请参考以下文章

BackgroundMediaPlayer 在 Windows Phone 8.1 中不起作用

在 windows silverlight 8.1 中不显示 AdControl

旋转后调整网格大小 Windows phone 8.1

Windows 8.1 背景音频播放器在应用程序的其他页面中不起作用

SystemTriggerType SmsReceived 任务在 windows phone 8.1 通用应用程序中不起作用

pip install pygame 在 Windows 8.1 中不起作用,但是我已经通过( C:\Python34\ )给出了路径。我该怎么办? [复制]