wpf - 当存在基于触发器隐藏显示元素的复杂数据模板时,我的 ListView 或 ListBox 控件大小不会缩小?

标签 wpf silverlight xaml listview height

我有一个 ListView 元素,每个 ListViewItem 都有一个 DataTemplate,定义如下。运行时,ListView 的高度不会折叠到 View 中的项目上,这是不良行为:

<DataTemplate x:Key="LicenseItemTemplate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"  />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding company}"></TextBlock>
        <Grid Grid.Row="1" Style="{StaticResource HiddenWhenNotSelectedStyle}">
            <Grid.RowDefinitions>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Grid.Row="0">ClickIt</Button>
        </Grid>
    </Grid>
</DataTemplate>

外部网格的第二行应用了如下所示的样式。该样式的目的是公开所选数据项的详细 View :

<Style TargetType="{x:Type Grid}" x:Key="HiddenWhenNotSelectedStyle" >
    <Style.Triggers>
        <DataTrigger
            Binding="{Binding Path=IsSelected, 
                        RelativeSource={
                        RelativeSource 
                        Mode=FindAncestor, 
                        AncestorType={x:Type ListViewItem}
                        }
                        }" 
            Value="False">
            <Setter Property="Grid.Visibility" Value="Collapsed" />
        </DataTrigger>
        <DataTrigger
            Binding="{Binding Path=IsSelected, 
                        RelativeSource={
                        RelativeSource 
                        Mode=FindAncestor, 
                        AncestorType={x:Type ListViewItem}
                        }
                        }" 
            Value="True">
            <Setter
                Property="Grid.Visibility"
                Value="Visible"
            />
        </DataTrigger>
    </Style.Triggers>
</Style>

ListView 呈现如下: Height of ListView is twice what it should be.
(来源:finitesolutions.com)

当没有选择任何元素时,所需的外观是这样的: Height of ListView is collapsed to list items.
(来源:finitesolutions.com)

...当然,当第二个网格通过选择可见时,ListView 的高度会调整以容纳附加内容。我该怎么做才能获得所需的行为?

最佳答案

在 TechEd 与 WPF 人员讨论该问题时,我向一位 Microsoft 员工展示了这个问题。他一头雾水。

我们下载了一个工具,该工具可查询 WPF 布局并将容器识别为 ListView 中的“虚拟化堆栈面板”元素。

在后续电子邮件中,他写道:“这是 VirtualizingStackPanel 的错误。我已经打开了一个关于它的错误。希望它可以在未来的版本中修复。解决方法(使用 StackPanel)目前应该没问题,只要您不需要 ListView 来虚拟化其内容即可。

该错误涉及 VSP Measure 算法中的一个步骤,该步骤会记住有史以来发现的最大尺寸,并强制所有 future 的 Measure 调用报告至少同样大的尺寸。在您的情况下,VSP 最初是在触发任何触发器之前进行测量的,因此它会计算大小,就好像所有内容都可见一样。当触发器触发并折叠按钮时,测量算法会计算正确的(小)尺寸,但随后会强制结果再次变大。该评论提到了如何在滚动时避免不必要的重新布局,但即使没有滚动,代码也会运行。”

解决方法包括使用以下代码重新模板化 ListView:

<ListView.ItemsPanel>
  <ItemsPanelTemplate>
    <StackPanel/>
  </ItemsPanelTemplate>
</ListView.ItemsPanel>

这使得列表行为能够按预期工作,但它的缺点是不具备 VirtualizingStackPanel 的内存管理功能。对于我的使用来说,这是合适的;列表项一次不会超过 2000 个左右。

关于wpf - 当存在基于触发器隐藏显示元素的复杂数据模板时,我的 ListView 或 ListBox 控件大小不会缩小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2955591/

相关文章:

.net - 如何使用 DataContext 属性在 XAML 中的窗口上设置 ViewModel?

c# - 分配克隆后如何检查模型是否更改

silverlight - 设置 Silverlight 起始页

wpf - 将 LayoutTransform 应用于 DataGridCell 内容时的性能问题

.net - 在 WP8 上,我应该为 MultiBinding 类引用哪个程序集

WPF 如何让 UserControl 继承 Button?

wpf - 加载 Dicom 图像并显示它 - 使用 ClearCanvas 库

c# - 在 Silverlight 中发出 Web 请求的问题

silverlight - 我可以在没有 IIS 的情况下运行 XAP 吗?

c# - 在 Xamarin.Forms 中绑定(bind)自定义 View