停止/抑制ObservableCollection.oncollectionChanged事件

发布于 2025-01-22 08:42:23 字数 2884 浏览 4 评论 0原文

我添加了类

public class ObservableCollectionEx<T> : ObservableCollection<T>
{
    public bool SuppressEvents { get; set; } = true;

    public ObservableCollectionEx(): base() {}
    public ObservableCollectionEx(IEnumerable<T> collection): base(collection){}
    public ObservableCollectionEx(List<T> list): base(list){}

    public void RaiseCollectionChangedEvent()
    {
        SuppressEvents = false;

        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!SuppressEvents)
            base.OnCollectionChanged(e);
    }
}

ViewModel


public ObservableCollectionEx<MyModel> myCollection = new ObservableCollectionEx<MyModel>();

Method1()
{
   myCollection.SuppressEvents = true;
   //some changes in Obs Collection.
   // some add/remove/insert operations on collection
   myCollection.RaiseCollectionChangedEvent(); // works
}

Method2()
{
   myCollection.SuppressEvents = true;
   //some changes in Obs Collection.
   // some add/remove/insert operations on collection
   myCollection.RaiseCollectionChangedEvent(); // breaks
}

,在ViewModel中,我通过调用raisecollectionChangedEvent方法来更改之前和更改后通过对变量进行切换来抑制事件。它在某些情况下正在工作。在某些人中,它引发了一个无效的指针例外。我无法观察导致例外的原因。

ps 错误

信息 对象引用未设置为对象的实例

stacktrace 安卓: in Xamarin.forms.platform.android.gridlayoutspansizelookup.getSpansize(system.int32位置)[0x00000] [0x00000] [0x00000] [0x00000] [\ a \ a \ a \ a \ s \ s \ xamarin.forms.platform.android \ android \ android \ collectionView \ cluctionView \ grid gridlayoutspansizelookup.ccs:18 at AndroidX.RecyclerView.Widget.GridLayoutManager+SpanSizeLookup.n_GetSpanSize_I (System.IntPtr jnienv, System.IntPtr native__this, System.Int32 position) [0x00008] in D:\a\1\s\generated\androidx.recyclerview.recyclerview\obj\ Release \ monoandroid9.0 \生成\ src \ androidx.recyclerview.widget.gridlaylayoutmanager.cs:510

ios:ios: in Xamarin.forms.platform.ios.itemsviewController 1 [titemsview] .updateTemplatedCell(xamarin.forms.platform.ios.templeatedcell.templeatedcell cell,Foundation.nsIndEdpath Indexpath Indexpath in d:\ a \ a \ 1 \ 1 \ a \ 1 \ 1 \ s \ xamarin.forms.platform.ios \ collectionView \ itemsViewController.cs:278 at xamarin.forms.platform.ios.itemsviewController 1 [titemsview] [titemsview] .createmeAsememememementCell(Foundation.nsIndexpath Indexpath Indexpath Indexpath)[0x0007B] a \ 1 \ s \ xamarin.forms.platform.ios \ collectionView \ itemsViewController.cs:619

I have added the class

public class ObservableCollectionEx<T> : ObservableCollection<T>
{
    public bool SuppressEvents { get; set; } = true;

    public ObservableCollectionEx(): base() {}
    public ObservableCollectionEx(IEnumerable<T> collection): base(collection){}
    public ObservableCollectionEx(List<T> list): base(list){}

    public void RaiseCollectionChangedEvent()
    {
        SuppressEvents = false;

        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!SuppressEvents)
            base.OnCollectionChanged(e);
    }
}

ViewModel


public ObservableCollectionEx<MyModel> myCollection = new ObservableCollectionEx<MyModel>();

Method1()
{
   myCollection.SuppressEvents = true;
   //some changes in Obs Collection.
   // some add/remove/insert operations on collection
   myCollection.RaiseCollectionChangedEvent(); // works
}

Method2()
{
   myCollection.SuppressEvents = true;
   //some changes in Obs Collection.
   // some add/remove/insert operations on collection
   myCollection.RaiseCollectionChangedEvent(); // breaks
}

And in ViewModel, I'm suppressing the events by toggling the variable before the changes and after changes by calling the RaiseCollectionChangedEvent method. It is working in some scenarios. In some, it is throwing a null pointer exception. I'm not able to observe what causes the exception.

P.S.
Error

Message
Object reference not set to instance of an object

StackTrace
Android:
at Xamarin.Forms.Platform.Android.GridLayoutSpanSizeLookup.GetSpanSize (System.Int32 position) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.Android\CollectionView\GridLayoutSpanSizeLookup.cs:18 at AndroidX.RecyclerView.Widget.GridLayoutManager+SpanSizeLookup.n_GetSpanSize_I (System.IntPtr jnienv, System.IntPtr native__this, System.Int32 position) [0x00008] in D:\a\1\s\generated\androidx.recyclerview.recyclerview\obj\Release\monoandroid9.0\generated\src\AndroidX.RecyclerView.Widget.GridLayoutManager.cs:510

iOS:
at Xamarin.Forms.Platform.iOS.ItemsViewController1[TItemsView].UpdateTemplatedCell (Xamarin.Forms.Platform.iOS.TemplatedCell cell, Foundation.NSIndexPath indexPath) [0x00031] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ItemsViewController.cs:278 at Xamarin.Forms.Platform.iOS.ItemsViewController1[TItemsView].CreateMeasurementCell (Foundation.NSIndexPath indexPath) [0x0007b] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ItemsViewController.cs:619

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文