如果您开启虚拟化,因为数据网格的加载时间是可怕的,那么,这里的解决方案:
- 关闭虚拟化
假设/调用为“你的DataGrid的项目源绑定行“
public IEnumerable<Row> Rows {get; set;}
将属性添加到您的”行“类IsVisible并切换当你要加载的数据(而不是当UI线程决定,以解决绑定和装载每个控制)
这部作品的原因,是因为当你加载网格,它会检查结合,所有的行是不可见的,所以UI线程不必旋转所有行*列来创建它们,它可以转到它需要做的下一件事情。另一方面,您可以检测什么时候方便的时间将这些行变为可见,何时View.Visibility可见,何时ViewModel从某处加载数据,等等。因此,您完全可以控制。下面我使用任务(在后台线程中)迭代我的项目源(行),但在UI线程上设置可见性。
private _isVisible = false;
/// <summary>
/// is false by default, for performance when loading first time.
/// </summary>
public bool IsVisible
{
get { return _isVisible; }
set
{
if (_isVisible == value)
return;
_isVisible = value;
RaisePropertyChanged(() => IsVisible);
}
}
在视图中,当数据网格是装载不允许它通过将行的重复,在后台线程霸占UI线程,则可见性设置为true。即使您在后台线程中,IsVisible属性更改也会触发您更新。
private void OnGridLoaded(object sender, RoutedEventArgs e)
{
//sample bool checks, you might not need them...
if (firstTimeLoad && !_isDataGridLoaded)
{
Task.Factory
.StartNew(() =>
{
/*first time loading performance tweak*/
foreach (var row in _viewModel.Rows)
ExeOnUi(() => { row.IsVisible = true; });
_firstTimeLoad = false;
})
}
忘了补充ExeOnUi代码(你可以用其他的像whateverControl.Dispatcher.CheckAccess检查访问,我只是用Microsoft.Practices。服务定位器):
static void ExeOnUi (Action action)
{
var srv= ServiceLocator.Current.GetInstance<IDispatchService>();
if (srv.CheckAccess())
action.Invoke();
else
srv.Invoke (action);
}
当你说删除虚拟化后的性能很糟糕,加载或滚动时可怕。如果它的负载,有一个解决方案,这将使它不可怕,滚动是另一个问题... – 2012-03-30 19:50:04
它只在负载。所有性能命中都在包含DataGrid的窗口的Show方法上。通过行虚拟化,可以在DataGrid中显示2,500条记录,并显示200ms。没有行虚拟化需要28秒。 – WPFNewbie 2012-03-30 20:17:39
为你增加了一些代码......前几天在工作中只需调整性能,就像魅力一样工作 – 2012-03-30 20:36:04