我有一个DataGridView,它从自定义(CSLA)列表对象中读取数据。数据集可能有100,000条记录,显然我不想一次性显示它们,因为一方面加载需要很长时间。
我认为如果我能读取第一个(例如)20个记录并且在滚动到列表末尾时这样做会很好,它会读取下一个20并将它们添加到DataGridView。
我已经尝试了各种方法,主要是使用从DataGridView继承的自定义类来捕获滚动事件并引发添加新记录的事件。我将包括以下代码:
Public Class TestDGV
Inherits DataGridView
Public Sub New()
AddHandler Me.VerticalScrollBar.ValueChanged, AddressOf vsScrollEvent
AddHandler Me.RowsAdded, AddressOf vsRowsAddedEvent
End Sub
Private Sub vsScrollEvent(ByVal sender As Object, _
ByVal e As EventArgs)
With DirectCast(sender, ScrollBar)
If .Value >= (.Maximum - .LargeChange) Then
RaiseEvent ScrollToEnd()
End If
End With
End Sub
Private Sub vsRowsAddedEvent(ByVal sender As Object, ByVal e As EventArgs)
ScrollbarOn()
End Sub
Public Event ScrollToEnd()
Public Sub ScrollbarOff()
Me.VerticalScrollBar.Enabled = False
End Sub
Public Sub ScrollbarOn()
Me.VerticalScrollBar.Enabled = True
End Sub
End Class
虽然这种(有点)有效,但它可能是错误的。最大的问题是,如果您使用鼠标滚动DataGrid,它将陷入循环,因为它在添加数据后处理滚动条的ValueChanged事件。这就是我添加ScrollbarOff和ScrollbarOn的原因 - 我在获取新记录之前和之后调用它们,这会暂时禁用滚动条。
的问题在于重新启用滚动条后,它不会跟踪当前的鼠标状态,因此如果您用鼠标按住“向下”按钮(或单击滚动条的一部分)它在添加新记录后停止滚动,您必须再次单击它。
此外,它似乎并不是一种特别优雅的做事方式。
以前有没有人这样做过,你是怎么做到的?
干杯。
答案 0 :(得分:0)
也许您可以减少结果集并使用<<和>>一种分页控制。 Nerd Dinner演示使用LINQ推出了一个优雅的解决方案:
//
// GET: /Dinners/
// /Dinners/Page/2
public ActionResult Index(int? page)
{
const int pageSize = 20;
var upcomingDinners = dinnerRepository.FindUpcomingDinners();
var paginatedDinners = upcomingDinners.Skip((page ?? 0) * pageSize)
.Take(pageSize)
.ToList();
return View(paginatedDinners);
}
答案 1 :(得分:0)
使用DataGridView的virtual
属性怎么样?
有关示例,请参阅Implementing Virtual Mode with Just-In-Time Data Loading in the Windows Forms DataGridView Control。