【问题标题】:Consolidated Scrolling - "Pixel by Pixel" + "Item by Item"合并滚动 - “逐个像素”+“逐项”
【发布时间】:2011-08-12 06:25:21
【问题描述】:

我有一个拖放框架,其中已经存在滚动支持(逐像素滚动)。这在未启用虚拟化的情况下效果很好,但如果启用了它就会搞砸。
由于滚动的逻辑基于视口高度,并且根据 MSDN,我们已经 -

MSDN- 如果 CanContentScroll 为 true,则 ExtentHeight、ScrollableHeight、ViewportHeight 和 VerticalOffset 属性的值是项目数。如果 CanContentScroll 为 false,则这些属性的值是与设备无关的像素。此外,如果启用了虚拟化,则 ExtentHeight 表示 - ScrollViewer 中的项目总数,而视口高度表示当前可见的项目数。

所以滚动力工作我想要类似的东西——

ScrollToContent(ScrollViewer, CurrentMousePositionWRTScrollViewer)
{ 
   if(ScrollViewer's Viewport Height is in terms of Pixel)
{
----------Do Pixel by Pixel Scrolling --------
}
else if(ScrollViewer's Viewport Height represents number of items visible)
{ 
--------- Do Item by Item Scrolling ---------
}

我尝试检查“CanContentScroll = false”,检查是否启用了虚拟化,但即使这样也能正常工作,因为我发现即使 CanContentScroll 为 true 视口高度 dint 表示可见项目的数量,但它等于实际高度。但是在另一个列表框上它显示 - 可见项目的数量。

滚动的实际代码 -

private void ScrollToContent(ScrollViewer scrollViewer, Point point)
    {
        double verticalScrollOffset = 0.0;
        double scrollDifference = 30.0;
        double scrollDefaultOffset = 40.0;

        if (scrollViewer == null) return;
        if (scrollViewer.ViewportHeight != scrollViewer.ExtentHeight)
        {
                if (scrollViewer.ViewportHeight - point.Y < scrollDifference)
                {
                    // See if we need to scroll down
                    verticalScrollOffset = scrollDefaultOffset;
                }
                else if (point.Y < scrollDifference)
                {
                    // See if we need to scroll up
                    verticalScrollOffset = -scrollDefaultOffset;
                }
                // Scroll up or down
                if (verticalScrollOffset != 0.0)
                {
                    verticalScrollOffset += scrollViewer.VerticalOffset;
                    if (verticalScrollOffset < 0.0)
                    {
                        verticalScrollOffset = 0.0;
                    }
                    else if (verticalScrollOffset > scrollViewer.ScrollableHeight)
                    {
                        verticalScrollOffset = scrollViewer.ScrollableHeight;
                    }
                    scrollViewer.ScrollToVerticalOffset(verticalScrollOffset);
                }
        }
    }

我错觉虚拟化是罪魁祸首,但在检查了 IsVirtualization 属性后,我注意到虚拟化在这里不是问题(两个列表框都是如此).. 知道可能的情况是什么吗??
问题是 - 我有 2 个列表框(几乎相似)在一种情况下我得到 视口高度 == 可见项目数 但是在其他情况下 视口高度 = 实际高度 ..

可能的原因是什么??

【问题讨论】:

    标签: wpf drag-and-drop virtualization scrollviewer


    【解决方案1】:
    bool isVirtualizing = (bool)scrollViewer.GetValue(VirtualizingStackPanel.IsVirtualizingProperty);
    VirtualizationMode mode = (VirtualizationMode)scrollViewer.GetValue(VirtualizingStackPanel.VirtualizationModeProperty);
    

    【讨论】:

    • 嗯,谢谢!!我在想虚拟化是这里的罪魁祸首,因为滚动不起作用。
    【解决方案2】:

    Answer Actual Height Vs Viewport Height and Scrolling Issue

    代码:在启用虚拟化的情况下,我使用选定的项目来逐项目滚动

     // Manage vertical scrolling. 
            if (scrollViewer.ViewportHeight != scrollViewer.ExtentHeight)
            {
                // NOTE :MSDN- If CanContentScroll is true, the values of the ExtentHeight, ScrollableHeight, ViewportHeight, and VerticalOffset
                // properties are number of items. If CanContentScroll is false, the values of these properties are Device Independent Pixels.
                // Also If Virtualization is Enabled then ExtentHeight Represents - TotalNumber of Items in ScrollViewer and Viewport Height
                // Represents Count of Items currently visible.
                if (scrollViewer.CanContentScroll == false)
                {
                    if (scrollViewer.ViewportHeight - point.Y < scrollDifference)
                    {
                        // See if we need to scroll down
                        verticalScrollOffset = scrollDefaultOffset;
                    }
                    else if (point.Y < scrollDifference)
                    {
                        // See if we need to scroll up
                        verticalScrollOffset = -scrollDefaultOffset;
                    }
    
                    // Scroll up or down
                    if (verticalScrollOffset != 0.0)
                    {
                        verticalScrollOffset += scrollViewer.VerticalOffset;
    
                        if (verticalScrollOffset < 0.0)
                        {
                            verticalScrollOffset = 0.0;
                        }
                        else if (verticalScrollOffset > scrollViewer.ScrollableHeight)
                        {
                            verticalScrollOffset = scrollViewer.ScrollableHeight;
                        }
    
                        scrollViewer.ScrollToVerticalOffset(verticalScrollOffset);
                    }
                }
                else
                {
                    if (scrollViewer != null)
                    {
                        // To ControlScrolling Speed - as we're doing Item By Item Scrolling now, it would be quite fast so add a time gap.
                        if (DateTime.Now.Subtract(lastScrollTime).TotalMilliseconds > 200)
                        {
                            if (scrollViewer.ActualHeight - point.Y < scrollDifference)
                            {
                                // See if we need to scroll down
                                verticalScrollOffset = scrollDefaultOffset;
                            }
                            else if (point.Y < scrollDifference)
                            {
                                // See if we need to scroll up
                                verticalScrollOffset = -scrollDefaultOffset;
                            }
    
                            if (verticalScrollOffset != 0.0)
                            {
                                // Scroll Content upwards 
                                if (verticalScrollOffset < 0 && scrollViewer.VerticalOffset > 0) // Also check if there are any non visible elements in scrollviewer
                                {
                                    scrollViewer.LineUp();
                                    lastScrollTime = DateTime.Now;
                                }
                                else if (verticalScrollOffset > 0 &&
                                    scrollViewer.VerticalOffset < scrollViewer.ExtentHeight - scrollViewer.ViewportHeight)
                                {
                                    scrollViewer.LineDown();
                                    lastScrollTime = DateTime.Now;
                                }
                            }
                        }
                    }
                }
            }
    

    【讨论】:

    • 嗨 Rohit,即使在启用虚拟化并且 CanContentScroll = True 时,您的代码是否会逐像素滚动?你在哪里连接这个方法? SelectedItemChanged 还是 Scrolling?
    • Leo,很抱歉,我很久以前就遇到过这个问题,我不再从事这个项目了。也不记得了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多