2

我正在使用 itemscontrol 来保存许多不同大小的控件。由于需要显示的控件数量,我决定启用虚拟化(在某些情况下“加载”控件需要一秒钟左右的时间,我真的需要将它们显示在一个长列表中,而不是使用某种崩溃)。

下面是我所拥有的一个简单测试(我正在使用这里提到的反射黑客)。问题是垂直滚动条上的拇指在您拖动时会更新,我认为这是有道理的,因为滚动查看器本身会随着新控件的出现而即时更新,但我想知道是否有解决方案?

是否可以进行虚拟化、基于像素的滚动大小反映所有控件而不仅仅是其处理的控件的拇指?

public class A { public double Height { get; set; } };

    public partial class MainWindow : Window
    {
        public List<A> Data { get; set; }

        public MainWindow()
        {
            var r = new Random();
            Data = new List<A>();
            for (int i = 0; i < 250; ++i)
            {
                Data.Add(new A() { Height = r.Next(10, 500) });
            }

            DataContext = this;
            InitializeComponent();
        }
    }

<ItemsControl ItemsSource="{Binding Data}" VirtualizingStackPanel.IsVirtualizing="True"
                          ScrollViewer.CanContentScroll="True">

        <ItemsControl.Template>
            <ControlTemplate>
                <ScrollViewer>
                    <ItemsPresenter />
                </ScrollViewer>
            </ControlTemplate>
        </ItemsControl.Template>

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel local:PixelBasedScrollingBehavior.IsEnabled="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <UniformGrid Columns="4">
                    <Label Content="label" Height="{Binding Height}"/>
                    <TextBox />
                    <UniformGrid Rows="2">
                        <Button />
                        <Button />
                    </UniformGrid>
                    <Slider/>
                </UniformGrid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

作为次要问题。为了查看禁用虚拟化时花费了这么长时间,我从 StackPanel 派生了 Measure/Arrange 函数,发现所有加载时间都花在了这些函数上。在我的情况下,测量时间为 600 毫秒,排列时间为 200 毫秒。WPF 分析工具也指出布局是杀手。这似乎是一个非常长的时间。诚然,像这样渲染 250 个控件(根据 Snoop 是 10k 个元素)并不是您最想做的事情,但是任何人都可以解释为什么需要这么长时间吗?是否在创建新控件时更新整个布局?我已经为 Slider 控件尝试了一些自定义模板,以尝试减少它使用的元素的数量并取得了一些成功,但后来我失去了功能。

4

0 回答 0