C# 当内容高度可变时,Listbox滚动条拇指会改变大小

C# 当内容高度可变时,Listbox滚动条拇指会改变大小,c#,wpf,listbox,itemscontrol,C#,Wpf,Listbox,Itemscontrol,我有一个列表框,其中显示了许多对象,每个对象的高度可以根据每个对象的值的数量而变化 许多对象的高度为5线,而其他对象的高度为1线。列表框中的滚动条看起来不像这样,可能是由于虚拟化。当您滚动浏览时,滚动条上的拇指将根据当前实际放入框中的项目数量更改其大小。这使得拇指有时非常大,有时非常小 由于此列表框也包含在TabControl中,因此当您从一个选项卡切换到另一个选项卡时,当您返回到它时,列表框通常会滚动到不同的部分 有没有办法解决这样的问题 其他信息: 禁用虚拟化确实解决了滚动问题,但代价是初始

我有一个列表框,其中显示了许多对象,每个对象的高度可以根据每个对象的值的数量而变化

许多对象的高度为5线,而其他对象的高度为1线。列表框中的滚动条看起来不像这样,可能是由于虚拟化。当您滚动浏览时,滚动条上的拇指将根据当前实际放入框中的项目数量更改其大小。这使得拇指有时非常大,有时非常小

由于此列表框也包含在TabControl中,因此当您从一个选项卡切换到另一个选项卡时,当您返回到它时,列表框通常会滚动到不同的部分

有没有办法解决这样的问题

其他信息: 禁用虚拟化确实解决了滚动问题,但代价是初始显示速度变慢。但是,当水平调整列表框的大小时(垂直调整很好),调整列表框的大小会导致严重的延迟,我假设这是由于我的模板的宽度发生变化,并且需要在每个元素上重新绘制:

<DataTemplate DataType="{x:Type xmlset:Variable}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="170"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Border BorderThickness="1,0,0,1" BorderBrush="Black">
            <TextBlock Margin="2,2,0,2"  Text="{Binding Path=Identifier.Name, Mode=OneWay}"/>
        </Border>
        <ItemsControl IsTabStop="False" Grid.Column="1" ItemsSource="{Binding Path=Values, Mode=OneWay}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="120"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <Border Grid.Column="0" BorderThickness="1,0,0,1" BorderBrush="Black">
                            <TextBlock Margin="2,2,0,2" Text="{Binding Path=Optimization, Mode=OneWay}"/>
                        </Border>
                        <Border Grid.Column="1" Width="Auto" BorderThickness="1,0,1,1" BorderBrush="Black">
                            <TextBox Margin="0,2,0,2" BorderThickness="0" Text="{Binding Path=Value}" TextChanged="TextBox_TextChanged"/>
                        </Border>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</DataTemplate>

这是围绕字段的边缘绘制边框,以形成可视分组,其中val将延伸到内容大小。listbox还具有HorizontalContentAlignmment=Stretch,以确保其外观正确

------------------- - var - opt - val - - ------------- - - opt - val - - ------------- - - opt - val - ------------------- ------------------- -var-opt-val- - ------------- --opt-val- - ------------- --opt-val- -------------------
注意:如果需要在不同的问题中提问,请告诉我,我会将问题分开

禁用虚拟化或使列表框中的项目高度相等。如果您的物品少于100件左右,您可以不用虚拟化就可以生活。

为什么不关闭列表框本身的任何大小限制,让它根据内容调整大小,并将其包装到ScrollViewer中,为后者设置适当的大小

标记应如下所示:

    <ScrollViewer Width="640px" Height="480px">
        <ListBox>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!--Visualization of a list item-->
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>


如果以这种方式实现,我在滚动过程中没有看到拇指大小的变化。

在列表框上设置
ScrollViewer.CanContentScroll=“False”
,这将禁用所谓的“逻辑滚动”,即根据项目数而不是高度进行滚动(“物理滚动”)。

我有大约200个项目。我尝试通过使ItemsPanelTemplate成为StackPanel来禁用虚拟化,我看到最初加载速度较慢,但随后滚动速度更快。但是,滚动条的大小仍在不断变化,因此这并不能解决问题。如果不需要的话,我不想改变项目的大小,但是看起来我可能会改变。如果滚动查看器要填满一个窗口,有什么方法可以让它工作吗?这确实解决了拇指大小的问题,但是由于自动调整窗口的宽度和高度,调整窗口大小的速度非常非常慢。是的,确实如此。ScrollViewer用于填充父控件,就像填充任何其他控件一样,如下所示。拇指还可以。你指的是哪种调整尺寸的表演?在我的测试程序中,它运行在一台普通的笔记本电脑上,有一个200个项目的列表,调整窗口大小,所有内容看起来都是即时的。我在水平滚动时遇到了问题,因为拉伸时每个元素上的DataTemplate都会重新绘制。我在TabItem中以编程方式创建列表框。请参阅更新的问题。当HorizontalContentAlignment=Stretch而没有虚拟化时,这是否总是一个缺点?如果延迟的原因确实是宽度的计算,那么尝试一下这个方法。以编程方式处理ListBox的resize事件,在处理程序内部获取实际宽度(由于拉伸对齐而预先自动设置),关闭拉伸对齐并显式设置该宽度。重要补充:在虚拟化ListBox的情况下,将ListBox放置在ScrollViewer包装中会降低性能。这种降级的原因很简单:ScrollViewer将强制其子内容首先呈现,因此ListBox中有成百上千个项目将需要长时间暂停数秒。这也会禁用虚拟化,使其与ScrollViewer中的ListBox的行为相同。要解决这一问题,您必须进行自定义实现;正常的物理滚动需要计算的总高度。(滚动条拇指的大小基于当前相对于总高度的可见高度)可能是个愚蠢的问题,但如何在列表框中设置它?我可以在scrollviewer中包装我的列表框,但这会破坏滚轮,所以我需要这样做……这是一个愚蠢的问题:)