WrapPanel 中的 ListViewItem 在折叠时占用 space
ListViewItem in WrapPanel occupying space when collapsed
我有一个ListView
使用WrapPanel
作为它的ItemsPanel
,我直接使用ListViewItem
作为内容。但是当一个 ListViewItem.Visibility
是 Collapsed
时,你仍然可以看到它正在使用的 space。
首先,示例 XAML 代码类似于我使用的代码:
<Grid>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemContainerStyle="{DynamicResource ContainerStyle}">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}" x:Key="ContainerStyle">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="200" ItemWidth="200"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Red"/>
</ListViewItem>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Blue"/>
</ListViewItem>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Green"/>
</ListViewItem>
</ListView>
</Grid>
例如,当所有项目都可见时(上面的代码)我有这个:
但是如果我更改第一项使其折叠如下
<ListViewItem Margin="10" Visibility="Collapsed">
<Border Background="Red"/>
</ListViewItem>
结果是这样的:
我期望的是以下内容:
因此我不明白为什么它会这样,Collapsed
似乎表现得像 Hidden
。我直接将它应用到项目上,看不出还能做什么。
我尝试了不同的解决方案,最值得注意的是 this one about binding to Visibility in the style and 但没有成功,结果相同。
我认为您看到的问题与即使折叠,ListViewItem 仍然是 Item,WrapPanel 将检测到 3 个项目,而不是 2 个有关。
一个很好的工作解决方案似乎是在自定义面板中覆盖面板的 "Arrange" 方法。
我正在这个伟大的 class AlignableWrapPanel 的基础上工作(继承自 Panel,而不是 WrapPanel),我通过替换它来让它工作:
var child = children[i];
if (child == null) continue;
有了这个 :
var child = children[i];
if (child == null) continue;
if (child.Visibility == Visibility.Collapsed) continue;
方法有ArrangeOverride
、ArrangeLine
和MeasureOverride
。 ArrangeLine
有点不同,但是带有 if(child == null) continue;
的那一行很容易识别;只需在之后添加带有 Collapsed 的那个即可。
该解决方案适用于任何
接受的答案实际上没有提供解决方案,而是在其评论部分提供。
如果您设置 ItemWidth,WrapPanel 将为所有绑定到自身的项目保留 ItemWidth,无论是否可见。
这里的解决方法是不在 WrapPanel 上设置 ItemWidth,而是在 ItemTemplate 上设置 Width。
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel MinWidth="96" />
</DataTemaplate>
</ItemsControl.ItemTemplate>
我有一个ListView
使用WrapPanel
作为它的ItemsPanel
,我直接使用ListViewItem
作为内容。但是当一个 ListViewItem.Visibility
是 Collapsed
时,你仍然可以看到它正在使用的 space。
首先,示例 XAML 代码类似于我使用的代码:
<Grid>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemContainerStyle="{DynamicResource ContainerStyle}">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}" x:Key="ContainerStyle">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="200" ItemWidth="200"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Red"/>
</ListViewItem>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Blue"/>
</ListViewItem>
<ListViewItem Margin="10" Visibility="Visible">
<Border Background="Green"/>
</ListViewItem>
</ListView>
</Grid>
例如,当所有项目都可见时(上面的代码)我有这个:
但是如果我更改第一项使其折叠如下
<ListViewItem Margin="10" Visibility="Collapsed">
<Border Background="Red"/>
</ListViewItem>
结果是这样的:
我期望的是以下内容:
因此我不明白为什么它会这样,Collapsed
似乎表现得像 Hidden
。我直接将它应用到项目上,看不出还能做什么。
我尝试了不同的解决方案,最值得注意的是 this one about binding to Visibility in the style and
我认为您看到的问题与即使折叠,ListViewItem 仍然是 Item,WrapPanel 将检测到 3 个项目,而不是 2 个有关。
一个很好的工作解决方案似乎是在自定义面板中覆盖面板的 "Arrange" 方法。
我正在这个伟大的 class AlignableWrapPanel 的基础上工作(继承自 Panel,而不是 WrapPanel),我通过替换它来让它工作:
var child = children[i];
if (child == null) continue;
有了这个 :
var child = children[i];
if (child == null) continue;
if (child.Visibility == Visibility.Collapsed) continue;
方法有ArrangeOverride
、ArrangeLine
和MeasureOverride
。 ArrangeLine
有点不同,但是带有 if(child == null) continue;
的那一行很容易识别;只需在之后添加带有 Collapsed 的那个即可。
该解决方案适用于任何
接受的答案实际上没有提供解决方案,而是在其评论部分提供。
如果您设置 ItemWidth,WrapPanel 将为所有绑定到自身的项目保留 ItemWidth,无论是否可见。
这里的解决方法是不在 WrapPanel 上设置 ItemWidth,而是在 ItemTemplate 上设置 Width。
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel MinWidth="96" />
</DataTemaplate>
</ItemsControl.ItemTemplate>