WPF DataGrid:是否可以按列水平滚动,而不是像素(也就是内容滚动)

时间:2015-04-24 17:02:06

标签: wpf datagrid .net-4.0 wpfdatagrid horizontal-scrolling

在WPF DataGrid中,默认情况下会逐行内置滚动。也就是说,单击DataGrid中垂直滚动条上的向下箭头,然后向下向下滚动一行。但是,如果单击水平滚动条上的右箭头,则不会向右移动一列 - 您只需向右移动一些固定数量的像素。我想单击右箭头并向右滚动一列。同样,如果用户点击并拖动水平滚动条,我希望滚动只按列增量滚动,而不是按像素增量滚动。

是否可以设置WPF Datagrid,以便按列完成水平滚动,而不是像素?

编辑:我还希望用户能够通过单击并拖动拇指水平滚动,类似于垂直滚动按行工作的方式。

1 个答案:

答案 0 :(得分: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;
    }
相关问题