【问题标题】:Accurate scrollbar control in an ItemsControl with a VirtualizingStackPanel带有 VirtualizingStackPanel 的 ItemsControl 中的准确滚动条控件
【发布时间】:2017-08-26 01:39:02
【问题描述】:

我有一个使用 VirtualizingStackPanel 的 Itemscontrol 来显示一个巨大的(并且不断增长的)项目列表:

<ItemsControl Grid.Row="1" Name="ConversationItemsControl" VirtualizingStackPanel.VirtualizationMode="Recycling">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <ScrollViewer>
                <ItemsPresenter />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:Message />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

虚拟化就像一个魅力,但我无法正确管理滚动条。如果我尝试以编程方式(例如加载时)滚动到底部,就像我在非虚拟化 StackPanels 中所做的那样:

var scrollViewer = VisualTreeHelper.GetChild(ConversationItemsControl, 0) as ScrollViewer;
scrollViewer.ChangeView(null, double.MaxValue, 1f, true);

滚动查看器尝试滚动到底部,但并没有完全这样做——它总是在“真正的”底部之前停止一点。这在某种程度上是有道理的,因为 VirtualizingStackPanels 使用滚动值来确定要呈现哪些项目,但这完全是我的磨难,最终用户无法接受。

如何滚动到“真实”底部?如果我想完全向下滚动到某个项目的顶部位于视口顶部(除非“真实”底部自然而然地太近),我该怎么办?

【问题讨论】:

    标签: c# scroll uwp itemscontrol virtualizingstackpanel


    【解决方案1】:

    这是因为内置的 ItemsControl 类不支持虚拟化。您可以尝试使用默认使用 UI 虚拟化的 ListBox。

    如果您不想有选择行为,只需设置:

    <ListBox x:Name="lbCustom">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <ContentPresenter/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    

    然后类似:

     lbCustom.ScrollIntoView(lbCustom.Items[lbCustom.Items.Count - 1]
    

    【讨论】:

    • 谢谢!一件小事:在我的自定义 UserControl 中,我有时会替换 ItemsSource 并滚动到底部,但它相当有问题(向下滚动太远)。将 ItemsSource 设置为空列表并事先调用 UpdateLayout 可以缓解这种情况,我错过了什么吗?
    • 我还没有这样的东西,所以我不知道它的外观以及如何帮助您解决这个问题。您的故障可能有类似的来源:d
    猜你喜欢
    • 2011-01-02
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2010-12-27
    • 1970-01-01
    相关资源
    最近更新 更多