WPF ObservableCollection行为分析

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

是什么:

一个泛型用来通知的集合,源码定义如下:

 为什么用:

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<T>,给集合添加、移除方法内置了通知,此时,我们将需要展示在界面上的的数据集合定义为ObservableCollection就可以解决绝大数问题,代码如下:

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

二、ObservableCollection的坑

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

<ListBox ItemsSource="{Binding Collection}" />
<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{x:Static converters:MultiConverter.Instance}">
            <Binding Path="Collection" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

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

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

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

 然后我翻看ObsevableCollection的源码

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

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

如何解决:

两个解决办法:

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

<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{x:Static converters:MultiConverter.Instance}">
            <Binding Path="Collection" />
            <Binding Path="Collection.Count" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

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

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值