Консолидированная прокрутка - «Пиксель за пикселем» + «Элемент за элементом» - PullRequest
1 голос
/ 25 апреля 2011

У меня есть платформа Drag-Drop, в которой поддержка прокрутки уже есть (Pixel by Pixel scrolling). Это хорошо работает в случае, если виртуализация не включена, но если она включена, то она испортится.
Поскольку логика прокрутки основана на высоте Viewport и в соответствии с 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, высота окна просмотра в окне представляет количество видимых элементов, но оно равно фактическому рост. Однако в другом списке он показывает количество видимых элементов.

Актуальный код прокрутки -

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 списка (почти одинаковые). В одном случае я получаю Высота ViewPort == Количество видимых элементов Однако в другом случае Высота ViewPort = Фактическая высота ..

В чем может быть причина ??

Ответы [ 2 ]

1 голос
/ 25 апреля 2011
bool isVirtualizing = (bool)scrollViewer.GetValue(VirtualizingStackPanel.IsVirtualizingProperty);
VirtualizationMode mode = (VirtualizationMode)scrollViewer.GetValue(VirtualizingStackPanel.VirtualizationModeProperty);
0 голосов
/ 09 мая 2011

Ответ Фактическая высота в зависимости от высоты области просмотра и прокрутки

Код: Я использовал выбранный элемент для выполнения прокрутки элемента по элементу при включенной виртуализации

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