C# 检查 WPF DataGrid 中的可见行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/658258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check visible rows in a WPF DataGrid
提问by ctrlalt313373
I have a WPF DataGrid
, which when there are too many rows to view on the screen it gets a vertical scrollbar. What I would like to know is if there is a way to know what the top visible row is when the user is scrolling.
我有一个 WPF DataGrid
,当屏幕上有太多行要查看时,它会得到一个垂直滚动条。我想知道的是,当用户滚动时,是否有办法知道顶部可见行是什么。
Ideally I would like to be able to wire up an event to know when the user is scrolling and on scroll, check what the top visible row is in order to update some information.
理想情况下,我希望能够连接一个事件以了解用户何时滚动和滚动,检查顶部可见行是什么以更新一些信息。
回答by Bob King
It's sort of an overcomplicated way of doing it, but it may work. First, subclass DataGridRowsPresenter and override the OnViewportOffsetChanged method. Then, duplicate the standard control template for the datagrid, and replace the DataGridRowsPresenter with your own. I leave the details of hit testing for a row relative to the viewport up to you ;-).
这是一种过于复杂的方法,但它可能有效。首先,子类化 DataGridRowsPresenter 并覆盖OnViewportOffsetChanged 方法。然后,复制数据网格的标准控件模板,并将 DataGridRowsPresenter 替换为您自己的。我将与视口相关的一行命中测试的详细信息留给您;-)。
What are you trying to accomplish, specifically? Maybe we can come up with a better way, as this may be very brittle and requires a bunch of extra work (i.e. keeping the control template in sync if they update it).
你想要完成什么,具体是什么?也许我们可以想出一个更好的方法,因为这可能非常脆弱并且需要大量额外的工作(即,如果他们更新控制模板,则保持同步)。
回答by Bob King
Using the following method worked for me:
使用以下方法对我有用:
// mHorizontalScrollBar is the HorizontalScrollBar subclass control's instance
// Get the total item count
nTotalCount = DataGrid1.Items.Count;
// Get the first visible row index
nFirstVisibleRow = mHorizontalScrollBar.Value;
// Get the last visible row index
nLastVisibleRow = nFirstVisibleRow + nTotalCount - mHorizontalScrollBar.Maximum;
回答by skybluecodeflier
How about subscribing to the ScrollViewer.ScrollChanged event on the DataGrid's ScrollViewer? The event arguments for it are pretty extensive, describing how much the ScrollViewer moved and what its new Vertical offset is. Also, according to MSDN:
如何订阅 DataGrid 的 ScrollViewer 上的 ScrollViewer.ScrollChanged 事件?它的事件参数非常广泛,描述了 ScrollViewer 移动了多少以及它的新垂直偏移量是多少。另外,根据 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.
如果 CanContentScroll 为 true,则 ExtentHeight、ScrollableHeight、ViewportHeight 和 VerticalOffset 属性的值是项目数。如果 CanContentScroll 为 false,则这些属性的值是与设备无关的像素。
CanContentScroll is indeed the case for the ScrollViewer for a DataGrid.
CanContentScroll 确实是 DataGrid 的 ScrollViewer 的情况。
All you have to do is find the ScrollViewer:
您所要做的就是找到 ScrollViewer:
ScrollViewer scrollview = FindVisualChild<ScrollViewer>(dataGrid);
using an implementation of FindVisualChild that can be found in various places (like here: Finding control within WPF itemscontrol).
使用可以在不同地方找到的 FindVisualChild 实现(例如:在 WPF itemscontrol 中查找控件)。
回答by Sinatr
Detecting scrolling is as easy as
检测滚动很简单
<DataGrid ScrollViewer.ScrollChanged="DataGrid_ScrollChanged" />
Now you must get ScrollViewer instance:
现在你必须得到 ScrollViewer 实例:
void DataGrid_ScrollChanged(object sender, RoutedEventArgs e)
{
var scroll = FindVisualChild<ScrollViewer>((DependencyObject)sender);
...
}
(Not sure where is origin of FindVisualChild, but there are plenty of implementations, e.g. here)
(不确定 FindVisualChild 的起源在哪里,但有很多实现,例如这里)
And then you can
然后你可以
int firstRow = (int)scroll.VerticalOffset;
int lastRow = (int)scroll.VerticalOffset + (int)scroll.ViewportHeight + 1;