合并滚动 - “Pixel by Pixel”+“Item by Item”

时间:2011-04-25 10:48:45

标签: wpf drag-and-drop virtualization scrollviewer

我有一个Drag-Drop框架,其中已经存在滚动支持(Pixel by Pixel滚动)。如果没有启用虚拟化,但是如果启用虚拟化,那么这会很好。然后它就会搞砸了 由于滚动逻辑基于视口高度,因此根据MSDN我们 -

  

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

所以滚动dint工作我想要像 -

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”,检查虚拟化是否已启用,但即使该dint工作也是因为我发现即使CanContentScroll为真,Viewport高度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属性之后,我注意到虚拟化不是问题(对于两个列表框都是如此)..任何想法可能的情况是什么?
问题是 - 我有两个列表框(几乎相似)在一个案例中,我得到   ViewPort高度==可见项目数  但在其他情况下   ViewPort高度=实际高度 ..

可能的原因是什么?

2 个答案:

答案 0 :(得分:1)

bool isVirtualizing = (bool)scrollViewer.GetValue(VirtualizingStackPanel.IsVirtualizingProperty);
VirtualizationMode mode = (VirtualizationMode)scrollViewer.GetValue(VirtualizingStackPanel.VirtualizationModeProperty);

答案 1 :(得分:0)

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;
                            }
                        }
                    }
                }
            }
        }