【问题标题】:WPF DataGrid: Is it possible to horizontal scroll by column, rather than by pixel (aka content scrolling)WPF DataGrid:是否可以按列水平滚动,而不是按像素(又名内容滚动)
【发布时间】:2015-07-03 09:43:35
【问题描述】:

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

是否可以将 WPF Datagrid 设置为按列而不是按像素进行水平滚动?

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

【问题讨论】:

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


    【解决方案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;
        }
    

    【讨论】:

    • 感谢您的回复。这种基本方法似乎适用于滚动条两端的箭头(我必须对您的代码进行一些调整才能使其正常工作)。但是,如果用户拖动滚动条,他们会在两个位置之间快速摆动。也就是在拖拽的时候,调用GetColumnOffset的方法接收forward == true,然后forward == false,然后forward == true,等等。从而产生振荡。
    • 还有其他想法吗?我编辑了我的问题以澄清我确实希望能够单击并拖动拇指。抱歉,如果不清楚。
    猜你喜欢
    • 2012-04-08
    • 2023-03-22
    • 1970-01-01
    • 2012-05-26
    • 2015-12-28
    • 2011-02-18
    • 2015-10-23
    • 2012-06-27
    • 1970-01-01
    相关资源
    最近更新 更多