VirtualizingStackPanel 未正确处理折叠项目

发布于 2025-01-03 09:14:32 字数 3864 浏览 1 评论 0原文

我在 wpf 中有一个 ListView ,用于显示字段列表;根据属性值,某些字段可以在运行时折叠。它工作正常,只是 ListVIew 不会折叠为 ListViewItem 保留的空间,该空间在运行时折叠。

在此处输入图像描述

我能够在 Snoop 中看到额外的 ListViewItems(具有折叠的可见性),ListView 也会移动项目向上,但它不会调整其高度以消除空白!

我可以肯定地说,这是由于 VirtualizedStackPanel 所致,因为将 ItemsPanel 更改为 StackPanel 解决了问题。以下是相关的 ListView XAML:

<ListView
    x:Class="Wizards.FieldBinderModelListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Margin="0"
    VerticalAlignment="Top"
    HorizontalContentAlignment="Stretch"
    VerticalContentAlignment="Top"
    Background="White"
    BorderThickness="0"
    Grid.IsSharedSizeScope="True"
    KeyboardNavigation.DirectionalNavigation="Continue"
    Padding="1"
    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
    ScrollViewer.VerticalScrollBarVisibility="Hidden"
    SelectionChanged="ListViewSelectionChanged"
    SelectionMode="Single">
    <ListView.ItemsPanel>
       <ItemsPanelTemplate>
        <!--Works fine with StackPanel but not with VirtualizingStackPanel
          Explicitly added this PanelTemplate to show that it works with            
          StackPanel;ListView uses VirtualizingStackPanel as default panel 
          and causes same problem-->              
        <!--<StackPanel Orientation="Vertical" VerticalAlignment="Top"/>-->
          <VirtualizingStackPanel Orientation="Vertical" 
               VerticalAlignment="Top"/>
       </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemContainerStyle>
      <Style TargetType="{x:Type ListViewItem}">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Foreground" Value="Black" />
            </Trigger>
            <DataTrigger Binding="{Binding Status}"
                         Value="{x:Static local:Status.NotExisting}">
                <!--Hide the fields which are in NotExisting state; 
                  Need a trigger here as Status can be different -->
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
      </Style>
  </ListView.ItemContainerStyle>
  <ListView.ItemTemplate>
    <DataTemplate DataType="{x:Type View:FieldViewModel}">
       <local:FieldEditor
          Margin="0,2,0,0"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Top"
          HorizontalContentAlignment="Stretch"
          VerticalContentAlignment="Top"
          Padding="0">
          <!--<local:FieldEditor.Style>
              <Style TargetType="{x:Type local:FieldEditor}">
                <Style.Triggers>
                  <DataTrigger
                    Binding="{Binding Status}"
                    Value="{x:Static local:Status.NotExisting}">
                      <Setter Property="Visibility" Value="Collapsed" />
                  </DataTrigger>
                </Style.Triggers>
              </Style>
            </local:FieldEditor.Style>-->
        </local:FieldEditor>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

这是 VirtualizingStackPanel 中的错误吗?还有其他人遇到过类似的问题吗?有什么解决方法吗?


更新:

在连接时向 MS 报告了此错误 - https://connect.microsoft.com/VisualStudio/feedback/details/734113/virtualizingstackpanel-not-handling-collapsed-items- Correctly

I am having a ListView in wpf which is used to display list of fields; based on a property value some of the fields can be collapsed at run time. Its working fine except that ListVIew does not collapse the space reserved for ListViewItem's which got collapsed at run time.

enter image description here

I am able to see the extra ListViewItems in Snoop(having Visibility as Collapsed), ListView too shifts the items upwards but it doesn't adjusts its height to remove the empty space!

I can surely say that this is happening due to VirtualizedStackPanel as changing the ItemsPanel to StackPanel solves the issue. Here is the relevant ListView XAML:

<ListView
    x:Class="Wizards.FieldBinderModelListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Margin="0"
    VerticalAlignment="Top"
    HorizontalContentAlignment="Stretch"
    VerticalContentAlignment="Top"
    Background="White"
    BorderThickness="0"
    Grid.IsSharedSizeScope="True"
    KeyboardNavigation.DirectionalNavigation="Continue"
    Padding="1"
    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
    ScrollViewer.VerticalScrollBarVisibility="Hidden"
    SelectionChanged="ListViewSelectionChanged"
    SelectionMode="Single">
    <ListView.ItemsPanel>
       <ItemsPanelTemplate>
        <!--Works fine with StackPanel but not with VirtualizingStackPanel
          Explicitly added this PanelTemplate to show that it works with            
          StackPanel;ListView uses VirtualizingStackPanel as default panel 
          and causes same problem-->              
        <!--<StackPanel Orientation="Vertical" VerticalAlignment="Top"/>-->
          <VirtualizingStackPanel Orientation="Vertical" 
               VerticalAlignment="Top"/>
       </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemContainerStyle>
      <Style TargetType="{x:Type ListViewItem}">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Foreground" Value="Black" />
            </Trigger>
            <DataTrigger Binding="{Binding Status}"
                         Value="{x:Static local:Status.NotExisting}">
                <!--Hide the fields which are in NotExisting state; 
                  Need a trigger here as Status can be different -->
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
      </Style>
  </ListView.ItemContainerStyle>
  <ListView.ItemTemplate>
    <DataTemplate DataType="{x:Type View:FieldViewModel}">
       <local:FieldEditor
          Margin="0,2,0,0"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Top"
          HorizontalContentAlignment="Stretch"
          VerticalContentAlignment="Top"
          Padding="0">
          <!--<local:FieldEditor.Style>
              <Style TargetType="{x:Type local:FieldEditor}">
                <Style.Triggers>
                  <DataTrigger
                    Binding="{Binding Status}"
                    Value="{x:Static local:Status.NotExisting}">
                      <Setter Property="Visibility" Value="Collapsed" />
                  </DataTrigger>
                </Style.Triggers>
              </Style>
            </local:FieldEditor.Style>-->
        </local:FieldEditor>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

Is this a bug in VirtualizingStackPanel? Anyone else faced a similar issue? Any workarounds?


Update:

Reported this bug to MS on connect - https://connect.microsoft.com/VisualStudio/feedback/details/734113/virtualizingstackpanel-not-handling-collapsed-items-correctly

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱要勇敢去追 2025-01-10 09:14:32

我设法重现了你的问题。它看起来确实像是 VirtualizingStackPanel 中的一个错误。
解决方法是将隐藏项目的高度设置为零,而不是折叠它们:

<DataTrigger Binding="{Binding Status}" Value="False">
    <Setter Property="Height" Value="0" />
    <Setter Property="IsEnabled" Value="False"/>
    <!--<Setter Property="Visibility" Value="Collapsed" />-->
</DataTrigger>

I managed to reproduce your problem. It certainly looks like a bug in VirtualizingStackPanel.
A work around is to set the height of the hidden items to zero instead of collapsing them:

<DataTrigger Binding="{Binding Status}" Value="False">
    <Setter Property="Height" Value="0" />
    <Setter Property="IsEnabled" Value="False"/>
    <!--<Setter Property="Visibility" Value="Collapsed" />-->
</DataTrigger>
微暖i 2025-01-10 09:14:32

对于其他寻求继续依赖可见性但也删除额外间距的方法的人,我通过删除 ListBoxItem 样式中的填充来修复它:

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="Padding" Value="0"/>
    </Style>
</ListBox.ItemContainerStyle>

看起来 ListBoxItem 的默认 Padding 为 3。

For anyone else looking for a way to continue relying on Visibility but also remove the extra spacing, I fixed it by removing the Padding in the style for the ListBoxItem:

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="Padding" Value="0"/>
    </Style>
</ListBox.ItemContainerStyle>

It seems the ListBoxItem's default Padding is 3.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文