WPF DataGrid: Възможно ли е хоризонтално превъртане по колона, а не по пиксел (известен още като превъртане на съдържание)

В WPF DataGrid превъртането по ред е вградено по подразбиране. Това означава, че щракнете върху стрелката надолу върху вертикалната лента за превъртане в DataGrid и превъртете надолу с точно един ред. Въпреки това, ако щракнете върху стрелката надясно върху хоризонталната лента за превъртане, вие не се премествате надясно с една колона - вие просто премествате надясно определено количество пиксели. Бих искал да щракна върху стрелката надясно и да превъртя надясно с една колона. По същия начин, ако потребителят щракне и плъзне хоризонталната лента за превъртане, бих искал превъртането да се превърта само по стъпки на колони, а не по стъпки на пиксели.

Възможно ли е да настроите WPF Datagrid така, че хоризонталното превъртане да се извършва по колона, а не по пиксел?

РЕДАКТИРАНЕ: Бих искал също така потребителят да може да превърта хоризонтално, като щраква и плъзга палеца, подобно на начина, по който вертикалното превъртане би работило по ред.


person skybluecodeflier    schedule 24.04.2015    source източник


Отговори (1)


Едно решение би било да се обработи събитието ScrollViewer.ScrollChanged...

<DataGrid x:Name="myGrid" ScrollViewer.ScrollChanged="dg_ScrollChanged"/>

и програмно превъртете до следващото отместване на колоната, като това:

    private void dg_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        if (e.HorizontalChange != 0) // horizontal scroll
        {
            if (e.OriginalSource is ScrollViewer)
            {
                // scoll to column offset
                ScrollViewer sv = e.OriginalSource as ScrollViewer;
                sv.ScrollToHorizontalOffset(GetColumnOffset(e.HorizontalChange > 0, sv.HorizontalOffset - e.HorizontalChange, sv.ScrollableWidth));
                e.Handled = true;
            }
        }
    }

Ще трябва да напишете метода „GetColumnOffset“. Ето една бърза и мръсна реализация, която направих заедно. Вероятно бихте могли да го направите по-чист и аз не проведох задълбочен тест, за да може да съдържа грешки:

    private double GetColumnOffset(bool forward, double currentPos, double maxOffset)
    {
        ObservableCollection<DataGridColumn> Columns = myGrid.Columns;
        double columnPosition = 0;
        double maxColumnPosition = 0;
        double maxColumnIndex = 0;
        foreach (var column in Columns)
        {
            columnPosition += column.ActualWidth;
            if (columnPosition < maxOffset)
            {
                maxColumnPosition = columnPosition;
                maxColumnIndex = Columns.IndexOf(column);
            }
            if (forward && columnPosition > currentPos)
            {
                return columnPosition;
            }
        }

        if (!forward)
        {
            columnPosition = maxColumnPosition;
            if (maxColumnPosition < currentPos)
            {
                return maxColumnPosition;
            }
            foreach (var column in Columns.Reverse())
            {
                if (Columns.IndexOf(column) <= maxColumnIndex)
                {
                    columnPosition -= column.ActualWidth;
                    if (columnPosition < currentPos)
                    {
                        return columnPosition;
                    }
                }
            }
        }

        return 0;
    }
person Gordon True    schedule 24.04.2015
comment
Благодаря ви за отговора. Този основен подход изглежда работи за стрелките в двата края на лентата за превъртане (трябваше да направя редица корекции на вашия код, за да работи). Въпреки това, ако потребителят плъзне лентата за превъртане, той получава много бързи колебания между две позиции. Тоест при плъзгане методът, извикващ GetColumnOffset, получава forward == true, след това forward == false, след това forward == true и т.н. Така колебанията. - person skybluecodeflier; 27.04.2015
comment
Някакви други идеи? Редактирах въпроса си, за да изясня, че наистина искам да мога да щракам и плъзгам палеца. Съжалявам, ако е било неясно. - person skybluecodeflier; 27.04.2015