如果可观察列表计数未更新,则引发事件

时间:2016-03-03 12:58:13

标签: c# winforms

我在Windows窗体应用程序中有一个项目,我在其中创建了一个事件。当我点击浏览器中的任何页面(即FiddlerApplication.AfterSessionComplete)时,会引发此事件。现在,每当事件发生时,我都会将数据添加到ObservableCollection中。要检查列表计数是否在增加,我正在使用ObservableCollection的CollectionChanged事件。如果列表计数没有增加,我想要触发事件。

ObservableCollection<Session> Sessions = new ObservableCollection<Session>();
public void FetchSession() {
        #region AttachEventListeners        
        FiddlerApplication.AfterSessionComplete += new SessionStateHandler(FiddlerApplication_AfterSessionComplete);
        Sessions.CollectionChanged += Sessions_CollectionChanged;

}
void Sessions_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
   //this fires when Collection count changes
}

void FiddlerApplication_AfterSessionComplete(Session oSession)
{
     Monitor.Enter(Sessions);
     Sessions.Add(oSession);
     Monitor.Exit(Sessions);
}

ObservableCollection类中没有它们可以告诉我收集计数没有增加。我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

您可以创建ObservableCollecton<T>的子类,并在调用CollectionChanged事件之间未更改Count时添加您自己的自定义事件。因此,您基本上保留一个存储集合Count的私有字段,并在下一个CollectionChanged事件中将当前Count与先前计数进行比较。如果它们相等,则提升您的自定义事件。

可能的实现如下:

public delegate void CountEqual(object sender, EventArgs e);

public class ObservableCountCollection<T>: ObservableCollection<T>
{
    public CountEqual CountUnchanged;

    private int _previousCount;
    private object locker = new object();

    public ObservableCountCollection()
    {
        this.CollectionChanged += ObservableCountCollection_CollectionChanged;
        _previousCount = 0;
    }

    void ObservableCountCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        bool raiseEvent = false;
        var unchanged = CountUnchanged;
        lock(locker)
        {
            raiseEvent = _previousCount == this.Count;
            _previousCount = this.Count;
        }
        if (raiseEvent && unchanged!=null)
        {
            unchanged(this, new EventArgs());
        }
    }
}

请注意,NotifyCollectionChangedEventArgs类型确实具有Action属性。对于这个系列,我想你也可以做到

raiseEvent = (e.Action == NotifyCollectionChangedAction.Replace || 
              e.Action == NotifyCollectionChangedAction.Move);

因此您不需要保留计数和锁定构造,但如果您能够在集合上调用AddRange,我就不会测试它是如何工作的。我留下任何后续问题。