【问题标题】:WPF Layout Performance-Penalty using ColumnSpanWPF 布局性能 - 使用 ColumnSpan 的惩罚
【发布时间】:2010-08-15 14:43:54
【问题描述】:

我有一个类似于下面显示的简化示例的网格。网格中有更多元素,但问题在于 ListBox 和 TextBlock。

如果 TextBlock(或任何其他具有相同网格配置的元素)的 ColumnSpan 为 2,则每次更新 ListBox 的项都会非常慢。我看过 Perforator 和 VisualProfiler,但看不到任何特别的东西。如果我将第二个 ColumnDefinition 设置为固定宽度,则一切正常。如果我将第一个 RowHeight 设置为固定高度,也会发生同样的情况。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2">The column-span of this TextBlock seems to lead to an refresh-problem</TextBlock>
    <ListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding}"></ListBox>                
</Grid>

有人对此有更深入的了解,并且可以向我解释此构造是否为否或此处发生的其他情况。

【问题讨论】:

    标签: wpf wpf-controls


    【解决方案1】:

    问题在于列表框会在列表中创建所有可视元素,以确定哪个是最宽的,因为您的 GridColumn 的宽度设置为自动。如果您的列表包含许多项目或有一个复杂(繁重)的 ItemTemplate,那么您就有麻烦了。

    通常,ListBox 只为可见元素创建视觉元素(这是由 ItemsPanelTemplate 中的 VirtualizingStackPanel 完成的。

    另一种方法是设置一个在 95% 的时间都有效的默认宽度 - 然后在最后 5% 的下一列中使用 GridSplitter(这样用户可以加宽列表)。或者,您可以使用另一个面板(例如 DockPanel),它不会询问 ListBox 它想要多宽... :-)

    【讨论】:

    • +1 正如您所写:“ListBox 只为可见元素创建视觉元素”,但为什么不在解释的情况下呢?如果我为 ListBox 设置了一个固定的,这不会改变这种情况。这并不是一个真正的大问题,我使用 GridColumn 和网格拆分器的固定来解决它,但是它给了我一种不好的感觉:没有其他 WPF-Element 我使用的和 Grid 一样多。通常我不会注意到这种性能影响,但现在我知道并且我已经用这种结构做了很多应用程序,因此白白消耗了大量的 CPU 功率。
    • 问题在于网格如何处理空间的垂直分配。当您将一行设置为自动时 - 网格会与该行中的子项一起检查他们希望在可用高度为 Infinite 时有多大。 ListBox 遇到无限时将返回它所有可视子项的高度......但是,您在所有情况下都看不到它的原因是,在某些情况下,Grid 可以确定可用高度或可用的最大高度,因此将此值传递给 Arrange()-pass 中的 ListBox。列大小自动也是如此。
    猜你喜欢
    • 2011-08-17
    • 2012-11-11
    • 2013-02-12
    • 2018-01-27
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 2017-09-16
    相关资源
    最近更新 更多