如何在WPF中防止ObservableCollection无缘无故地刷新?
如何在WPF中防止ObservableCollection无缘无故地刷新?
我有一个使用C# WPF的项目,可以将DataGrid中的数据保存到SQL Server数据库的表中。
数据库中有两个表,即Factor和Commodity,它们彼此相关,并且DataGrid的ItemsSource由名为WHOLE_DATA_FACTOR的ObservableCollection填充,该集合来自Factor表。
DataGridComboBoxColumn的ItemsSource仅在程序加载时填充一次。
在RowEditEnding事件中插入Factor表后,我希望重新加载DataGrid的数据。
DataGridComboBoxColumn的ItemsSource在SELECT CommodityCode,CommodityName FROM dbo.Commodity的查询中填充,但我注意到在LoadDataAgian之后,集合中的项目开始刷新(就像在每个项目上移动),这使得程序变慢,而且DataGridComboBoxColumn的ItemsSource开始重新填充,而我并没有这样做。
以下是发生的情况的视频:
完整的源代码和数据库:
XAML:
DataGridComboBoxColumn的宽度为160,标题为“DataGridComboBoxColumn”,SelectedValueBinding绑定到CommodityID,DisplayMemberPath为CommodityName,SelectedValuePath为CommodityCode。
...
Code Behind:
MainWindow类是一个部分类,其中包含了Factor和Commodity的自定义模型和集合。在窗口加载时,会填充DataGrid的ItemsSource和DataGridComboBoxColumn的ItemsSource。在RowEditEnding事件中,将数据插入到Factor表中,并重新加载DataGrid的数据。
如果解释不清楚,请查看视频并在我的代码中进行评论。
最好的祝福。
问题出现的原因:
当修改ObservableCollection时,Target将被触发,并开始调用集合项的getter来更新自身。如果这种行为不符合需求,可以进行以下操作:
解决方法:
1. 将ObservableCollection替换为List。
2. 让类实现INotifyPropertyChanged接口。
3. 每当想要从代码中更新UI时,可以使用OnPropertyChanged显式地进行更新。
代码示例:
public partial class MainWindow : Window, INotifyPropertyChanged { // .. public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // .. } private void Window_Loaded(object sender, RoutedEventArgs e) { //Filling DataGrid by ObservableCollection WHOLE_DATA_FACTOR = new List(); var RST = dbms.Database.SqlQuery ("SELECT * FROM Factor").ToList(); foreach (var item in RST) WHOLE_DATA_FACTOR.Add(item); OnPropertyChanged(nameof(WHOLE_DATA_FACTOR)); // .. }
注意我创建了一个new List
感谢你花时间帮助,我按照你的建议做了,但问题仍然存在。我删除了DataGrid的ItemSource绑定,并用List替换了ObservableCollection,我通过编程方式填充了DataGrid,但即使如此,它仍然会开始调用getter {set; get;},我可以有完整的解决代码吗?
当然,你可以尝试使用下面的MainWindow代码,如果问题仍然存在,请告诉我。它应该只会在Window_Loaded中调用一次getter,而不是在MainDataGrid_RowEditEnding之后。
感谢,但最后在加载完成时,我遇到了这个错误:[错误链接]
你可以尝试在Window_Loaded中删除最后两个OnPropertyChanged调用,只保留第一个OnPropertyChanged(nameof(WHOLE_DATA_FACTOR));,然后重新构建和运行吗?
我按照你的建议做了,但这次它在RowEndEditing事件中出现了错误(该事件中没有任何内容)。对不起,你能下载并测试我的源代码吗?谢谢。
我刚刚尝试了代码,它完美运行没有任何问题!
让我们在聊天中继续这个讨论。[聊天链接]