最近做一个爬取数据的项目,用户操作过程中需要将爬取的数据绑定显示在看板上作为数据预览。
功能上线后测试发现会偶发UI卡死崩溃问题,查日志报错:某个ItemsControl与它的项源不一致 计数器XXXXXX
先说下我的数据显示的实现方式:
主窗体放置了一个DataGrid(wpf原生控件) 然后xaml里添加
ItemsSource="{Binding Path=DataGridModel.DymTable.DefaultView, IsAsync=True, UpdateSourceTrigger=PropertyChanged}"
从而直接绑定viewmodel中的DataTable(数据表)
由于之前测试发现改变DataTable(表格A)之后 表格可能不随之更新(比如增加删除列)于是额外增加一个DataTable(表格B) 用于实际数据操作 然后数据操作结束后 进行 表格A=表格B 以此触发WPF数据的绑定更新。
问题:RT有时候增加列到一定数据量 (超出当前表格显示范围 产生水平滚动条) 然后再生成一列数据时(行数增加),UI直接崩溃。找了很久 发现网上都是说啥使用ObservableCollection代替List 进行数据绑定 但是我使用的是DataTable进行绑定的 不想换成这种方式(主要是我的数据都是按列生成 而不是按行生成)
最后查找StackOverflow才找到解决方式(老外就是牛逼 啥问题都有解决方法)
即:
myListBox.Items.Refresh();
就是每次赋值数据源前 先刷新一下控件的items 已避免计数出现问题 具体原理不知
public void Refresh()
{
this.Dispatcher.Invoke(() => {
this.StaffAdminView.Items.Refresh();
this.dg_CaptureTable.Items.Refresh();
});
}
界面后台增加一个刷新函数,然后viewmodel更新数据源时 先调用一下该函数(可通过回调实现) 修改之后多次测试 暂未复现UI崩溃问题
纠正几点:
1.后面调整DataGrid Refresh的位置,在每次绑定新DataTable之后刷新控件
2.我之前出现问题的地方可能跟动态调整列宽,或者显示水平滚动条以及控制滚动条滚到最后一列有关系。后面绑定刷新完数据后再执行滚动条滚动命令,没有再次遇到报错