自定义滚动DataGridView [英] Custom scrolling of DataGridView

查看:129
本文介绍了自定义滚动DataGridView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有趣的问题,DataGridView绑定到BindingList< T> - 派生的数据源。

我正在尝试复制旧版WinSDK应用程序的行为。一行实时数据显示在DataGridView中,我使用BindingList来存储和更新数据。以异步方式接收新数据并将其插入"顶部"。 BindingList的。数据显示正确,但滚动行为难以复制。

现有系统将自动滚动"向上"当新数据出现时,并且仅当网格已经挂在顶部时(例如,FirstDisplayedScrollingRowIndex为0,它保持为零,即使在顶部插入新行)。如果在收到新数据时FirstDisplayedScrollingRowIndex为0,则网格不应滚动。

我可以通过捕获RowAdded和Scroll事件以过于复杂的方式执行此操作 - 除了在一种情况下。如果用户选择了已导航到屏幕外位置的行/单元格(例如,选择了第15行,但当前可见行2-10),则添加新行时收到的第一个事件不是RowAdded事件,但是Scroll事件强制所选行/单元格进入可见性(滚动网格以显示行12-20)。现在,不是阻止滚动(因为我没有"挂钩"到顶部),网格只是跳到用户看起来像"随机"的状态。 spot(在选定的行/单元格附近的某处)。

我不能简单地忽略大的Scroll跳跃,因为这可能是由于拇指移动而发生的。似乎没有任何方法可以确定Scroll事件被触发的原因(用户是这样做的,还是DataGridView的副作用,决定了所需的行/单元是否可见)。

有没有办法:

a)禁用"在行添加时选择可见" "特征"或者b)确定滚动发生的原因(用户动作或自动)或者c)完全不同的方式来创建相同的效果(挂到顶部)

谢谢!

I have an interesting problem with a DataGridView bound to a BindingList<T>-derived data source.

I'm trying to replicate the behavior of a legacy WinSDK application. A rows of live data are displayed in a DataGridView, and I use a BindingList to store and update the data. New data is received asynchronously and inserted to the "top" of the BindingList. The data shows up properly, but the scrolling behavior is difficult to replicate.

The existing system will automatically scroll "up" when new data appears if, and only if, the grid is already pegged to the top (e.g., FirstDisplayedScrollingRowIndex is 0, it stays zero, even as new rows are inserted at the top). If FirstDisplayedScrollingRowIndex is anything but 0 when new data is received, the grid should not scroll.

I can do this, in an overly complicated way, by trapping the RowAdded and Scroll events - except in one situation. If a user has selected a row/cell that has been navigated to a position off-screen (e.g., row 15 is selected, but rows 2-10 are currently visible), the first event I receive when a new rows is added is not the RowAdded event, but a Scroll event that is forcing the selected row/cell into visibility (the grid is scrolled so that rows 12-20 are displayed). Now, instead of preventing scrolling (as I wasn't "pegged" to the top), the grid just jumps to what seems to the user like a "random" spot (somewhere near the selected row/cell).

I can't simply ignore big Scroll leaps, as these could occur due to a thumb move. There doesn't appear to be any way to determine why the Scroll event was fired (did the user do this, or is it a side-effect of the DataGridView deciding the selected row/cell needed to be visible).

Is there any way to:

a) disable the "make selected visible on row addition" "feature" or
b) determine why the Scroll occurred (user action or automatic) or
c) a complete different way to create the same effect (peg to top)

Thanks!

推荐答案

您可能必须在数据更新之前获得FirstDisplayedScrollingRowIndex。  添加新数据,然后将FirstDisplayedScrollingRowIndex设置为前一个加上插入的新行数。  这会产生
没有滚动的错觉。

You may have to get the FirstDisplayedScrollingRowIndex prior to your data update.  Add the new data, then set the FirstDisplayedScrollingRowIndex to the previous plus the count of new rows inserted.  This will give the illusion that no scroll has occurred.

听起来插入的数据正在推送用户正在查看的数据,这样做的效果是控件已向上滚动)实际上,它继续查看原始的FirstDisplayedScrollingRowIndex(添加新行时不会更改
)。  尽管如此,这并没有给出非常好的用户体验!

It sounds like the data inserted is pushing the data that the user is viewing, down (giving the effect that the control has been scrolled up) when in actual fact, it is continuing to view the original FirstDisplayedScrollingRowIndex (which does not change when new rows are added).  This does not give for a very nice User Experience though!

如果你想在用户当前在第0行时进行'peg to top',那么就做一个if数据更新中的声明。  以下是一个示例:(未经测试,抱歉)

If you want to do the 'peg to top' if the user is currently at row 0, then just do an if statement in the data update.  Here is an example: (not tested, sorry)

Dim originalRowIndex as Integer = myDataGrid.FirstDisplayedScrollingRowIndex
Dim rowCount as Integer = myDataGrid.Rows.Count

' Perform data update


if originalRowIndex = 0 then
 myDataGrid.FirstDisplayedScrollingRowIndex = 0
else
 Dim newRowCount as Integer = myDataGrid.Rows.Count
 Dim rowsAdded as Integer = newRowCount - rowCount
 myDataGrid.FirstDisplayedScrollingRowIndex = originalRowIndex + rowsAdded
end if

还有!  此代码可能会进入DataGridview的'RowsAdded'事件。

ALSO!  This code might be able to go into the 'RowsAdded' event of your DataGridview.


这篇关于自定义滚动DataGridView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆