如何在WPF中防止ObservableCollection无缘无故地刷新?

16 浏览
0 Comments

如何在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开始重新填充,而我并没有这样做。

以下是发生的情况的视频:

mp4:https://ufile.io/p5azjp40

完整的源代码和数据库:

https://ufile.io/uxneng9r

XAML:

DataGridComboBoxColumn的宽度为160,标题为“DataGridComboBoxColumn”,SelectedValueBinding绑定到CommodityID,DisplayMemberPath为CommodityName,SelectedValuePath为CommodityCode。

...

Code Behind:

MainWindow类是一个部分类,其中包含了Factor和Commodity的自定义模型和集合。在窗口加载时,会填充DataGrid的ItemsSource和DataGridComboBoxColumn的ItemsSource。在RowEditEnding事件中,将数据插入到Factor表中,并重新加载DataGrid的数据。

如果解释不清楚,请查看视频并在我的代码中进行评论。

最好的祝福。

0
0 Comments

问题出现的原因:

当修改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(),所以为了更新绑定到List的Target,你需要给它一个新引用,你也可以在调用OnPropertyChanged之前使用WHOLE_DATA_FACTOR = WHOLE_DATA_FACTOR.ToList()。

感谢你花时间帮助,我按照你的建议做了,但问题仍然存在。我删除了DataGrid的ItemSource绑定,并用List替换了ObservableCollection,我通过编程方式填充了DataGrid,但即使如此,它仍然会开始调用getter {set; get;},我可以有完整的解决代码吗?

当然,你可以尝试使用下面的MainWindow代码,如果问题仍然存在,请告诉我。它应该只会在Window_Loaded中调用一次getter,而不是在MainDataGrid_RowEditEnding之后。

感谢,但最后在加载完成时,我遇到了这个错误:[错误链接]

你可以尝试在Window_Loaded中删除最后两个OnPropertyChanged调用,只保留第一个OnPropertyChanged(nameof(WHOLE_DATA_FACTOR));,然后重新构建和运行吗?

我按照你的建议做了,但这次它在RowEndEditing事件中出现了错误(该事件中没有任何内容)。对不起,你能下载并测试我的源代码吗?谢谢。

我刚刚尝试了代码,它完美运行没有任何问题!

让我们在聊天中继续这个讨论。[聊天链接]

0