我尝试使用System.Windows.Controls.GridView
(具体地说,它被Eto.Forms.GridView
Package )来显示一个大型数据集(1 m+行),但发现它无法使用。
从我所看到的情况来看,当设置GridView.ItemsSource
属性时,网格会立即调用GetEnumerator()
,因此在显示枚举的数据集之前会有很长的延迟。因此,我实现了一个解决方案,使用下面所示的代码快速显示网格。
基本上,该代码试图覆盖通常的List.GetEnumerator()
功能,并从底层列表中给予一小块行,然后利用INotifyCollectionChanged.CollectionChanged
事件添加剩余的行,一次添加一小块。
虽然该解决方案在初始负载上 * 相对 * 快速地显示网格方面起作用,但是存在许多问题,包括:
- 由于列表是通过线程填充的,因此它变得非常无响应,当然滚动条扩展的外观看起来并不美观;
- 最大的问题是,网格变得完全没有React的一分钟(+),每次你试图向下滚动。
有人知道我如何使DataGrid与大型IList数据源一起工作吗?请注意,我无法更改控件,因为我正在使用ETO.Forms来实现跨平台桌面UI功能。
- 谢谢-谢谢
// The underlying IList containing a large list of rows
IList<T> _underlyingList;
public IEnumerator<T> GetEnumerator() {
// Create an initial chunk of data to immediately return to the grid for display
long i = 0;
for (i = 0; i < _underlyingList.Count; i++) {
yield
return _underlyingList[i];
if (i > 100) break;
}
// Record the UI context so we can update the collection in that thread
var uiContext = SynchronizationContext.Current;
// Now we create a task that will populate the rest of the grid by
// raising "CollectionChanged" events to add the remaining rows.
Task.Run(() => {
// Create a temporary list to add to
var list = new List <T> ();
// Add to our list
for (long x = i; x < _underlyingList.Count; x++) {
list.Add(_underlyingList[x]);
// Every x items, fire a "CollectionChanged" event.
if (x % 1000 == 0) {
var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list);
// Invoke the CollectionChanged event on the UI thread
uiContext.Send(p => CollectionChanged?.Invoke(this, e), null);
list.Clear();
}
}
// Fire any last event as required.
if (list.Count > 0) {
var e = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list);
CollectionChanged?.Invoke(this, e);
uiContext.Send(p => CollectionChanged?.Invoke(this, e), null);
}
});
}```
1条答案
按热度按时间eimct9ow1#
尝试使用DynamicLayout来完成您要做的事情。Eto中的GridView功能非常有限,文档记录也非常糟糕。