在WPF DataGrid中,默认情况下会逐行内置滚动。也就是说,单击DataGrid中垂直滚动条上的向下箭头,然后向下向下滚动一行。但是,如果单击水平滚动条上的右箭头,则不会向右移动一列 - 您只需向右移动一些固定数量的像素。我想单击右箭头并向右滚动一列。同样,如果用户点击并拖动水平滚动条,我希望滚动只按列增量滚动,而不是按像素增量滚动。
是否可以设置WPF Datagrid,以便按列完成水平滚动,而不是像素?
编辑:我还希望用户能够通过单击并拖动拇指水平滚动,类似于垂直滚动按行工作的方式。
答案 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;
}