簡體   English   中英

ObservableCollection上的Observable.FromEventPattern

[英]Observable.FromEventPattern on ObservableCollection

我有一個ClassWrapper類和一個BaseClassWrapper類。 BaseClassWrapper具有ClassDTO類型的對象,並且在其內部具有ObservableCollection,這就是我要“觀察”的對象。 當我創建“ ClassWrapper”類型的對象並將一個項目添加到集合ClassWrapper.ClassDTO.MyCollection.Add(new OtherClass()) ,觀察者將無法使用。

但是,如果我在ClassWrapper(不是在BaseWrapper中)內創建ClassDTO或ObservableCollection,它會完美地工作。 為什么會這樣?

public class ClassWrapper : BaseClassWrapper
{
    public ClassWrapper()
    {
        Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
                (x => ClassDTO.MyCollection.CollectionChanged += x, x => ClassDTO.MyCollection.CollectionChanged -= x)
            .Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add ||
                        x.EventArgs.Action == NotifyCollectionChangedAction.Replace ||
                        x.EventArgs.Action == NotifyCollectionChangedAction.Remove)
            .Throttle(TimeSpan.FromMilliseconds(250))
            .Subscribe(x =>
            {
                RaisePropertyChanged(SomeProperty);
            });
    }
}

public abstract class BaseClassWrapper : ObservableObject // MVVM Light
{
    public ClassDTO ClassDTO { get; set; } = new ClassDTO();
}

public class ClassDTO
{
    public ObservableCollection<OtherClass> MyCollection { get; set; } = new ObservableCollection<OtherClass>();
}

我嘗試了代碼,每100毫秒添加了一個新項目,然后……至少我感到困惑,直到我不小心將鼠標懸停在Throttle並看到:

忽略可觀察序列中的元素,在指定的相對持續時間內,此元素之后是另一個元素。

我懷疑像我一樣,您希望Throttle()返回窗口中的最后一項。 即使它在ReactiveX.io中的描述是

僅在經過特定時間跨度時才從Observable發出一項,而不發出另一項

和文檔備注說:

對於元素之間的間隔永遠不大於或等於DueTime的流,結果流將不產生任何元素。

實際上,我過去曾經使用過這種方式,但是每次我都以某種方式遍歷該名稱,直到我記得實際的操作是在反跳 ,而不是在節流。

當我放慢計時器觸發時間(例如每300毫秒)時,我開始獲得結果。

返回窗口中最后一個事件的運算符是Sample ,而不是Throttle。 如果那是您想要的,則應使用

.Sample( TimeSpan.FromMilliseconds(300))

而不是Throttle

如果僅通知停止發出250毫秒后才更新UI,請使用Throttle

更新資料

為了測試此行為,我創建了一個控制台應用程序。 我對問題的代碼進行了一些修復,以使其得以編譯:

public class ClassWrapper : BaseClassWrapper
{
    public string SomeProperty { get; set; }
    public ClassWrapper()
    {
        Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>
                (x => ClassDTO.MyCollection.CollectionChanged += x, x => ClassDTO.MyCollection.CollectionChanged -= x)
            .Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add ||
                        x.EventArgs.Action == NotifyCollectionChangedAction.Replace ||
                        x.EventArgs.Action == NotifyCollectionChangedAction.Remove)
            .Throttle( TimeSpan.FromMilliseconds(250))
            .Subscribe(x =>
            {
                RaisePropertyChanged( ()=> SomeProperty);
            });
    }
}

應用程序的Main方法每100毫秒添加一個項目。 添加最后一項后250毫秒,將引發單個通知事件並顯示一條消息:

static async Task Main(string[] args)
{
    Console.WriteLine("Started");
    var c = new ClassWrapper();
    c.PropertyChanged += (sender, e) =>
    {
        Console.WriteLine($"Collection has {c.ClassDTO.MyCollection.Count} items");
    };

    for (int i = 0; i < 100; i++)
    {
        c.ClassDTO.MyCollection.Add(new OtherClass());
        await Task.Delay(100);

    }

    Console.ReadKey();
}    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM