WPF ObservableCollection行为分析

一、ObservableCollection是什么,为什么要使用它

是什么:

一个泛型用来通知的集合,源码定义如下:WPF ObservableCollection行为分析_第1张图片

 为什么用:

WPF是数据驱动界面,当后台数据变更时触发通知而更新界面,常规代码如下:

public event PropertyChangedEventHandler? PropertyChanged;

private int _id;
public int Id
{
    get => _id;
    set
    {
        _id = value;
        PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(nameof(Id)));
    }
}

这样写时后台变更Id,界面显示可以正常刷新。

但当我们使用集合时,问题就出现了,集合的添加、移除是不会触发set的,也就是说,我们后台添加集合时,不会发送通知,界面也就不会刷新,前台后台数据就不一致了。

此时ObservableCollection出现了,微软官方包装了Collection,给集合添加、移除方法内置了通知,此时,我们将需要展示在界面上的的数据集合定义为ObservableCollection就可以解决绝大数问题,代码如下:

private ObservableCollection _collection;
public ObservableCollection Collection { 
    get => _collection; 
    set 
    { 
        _collection= value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Collection)));
    }
}

二、ObservableCollection的坑

本来我一直用的舒舒服服,直到某一天遇到了Multibinding,先看如下Xaml代码:



    
        
            
        
    

上面一个ListBox的ItemSource和下面一个TextBlock的Text都绑定之前定义的集合Collection,唯一不同的就是上面是普通binding,下面是Multibinding。

当后台给Collection添加数据时,ListBox可以正常更新,TextBlock却一直不会更新、不会进Converter。

经过一个下午的调试和搜索,终于在StackoverFlow上找到了线索:

WPF ObservableCollection行为分析_第2张图片

 然后我翻看ObsevableCollection的源码

WPF ObservableCollection行为分析_第3张图片

 结果已经一目了然了,从源码看出,集合增删改查时会触发两个PropertyChanged(Count和Indexer)和一个CollectionChanged。

而Multibinding不接收CollectionChanged的通知,只接收PropertyChanged,但集合的增删改查并不会触发定义的集合这个属性的PropertyChanged,故如此绑定的界面并不会刷新。

如何解决:

两个解决办法:

1、在Multibinding里加一个集合数量的绑定,这样就能收到OnCountPropertyChanged()此方法的通知从而触发进Converter处理数据,代码如下:


    
        
            
            
        
    

2、在ObservableCollection上面再封装一层添加引发集合的PropertyChanged逻辑。

相关链接:https://stackoverflow.com/questions/5583830/multibinding-with-multivalueconverter-does-not-update

你可能感兴趣的:(WPF封神之路,wpf)