簡體   English   中英

.net c# 限制 observablecollection 中的條目數

[英].net c# Limit number of entries in observablecollection

我有一個 WPF 應用程序,其中 UI 有一個列表框。 列表框綁定了 ObservableCollection。 日志類實現 INotifyPropertyChanged。

該列表將顯示應用程序的連續日志記錄。 只要應用程序正在運行。 ObservableCollection 的大小不斷增長。 一段時間后,我收到內存不足異常。 我想在列表控件中顯示最新的 1000 個條目。 對此的任何建議都會有很大幫助!!

XAML:

                    <DataGrid AutoGenerateColumns="False" SelectedValue="{Binding SelectedLog}" SelectionUnit="FullRow" SelectionMode="Single" Name="dataGridLogs" 
                      ItemsSource="{Binding Path=LogList}"  CanUserReorderColumns="True" CanUserResizeRows="True" CanUserDeleteRows="False"  IsReadOnly="True"
                      CanUserAddRows="False" EnableColumnVirtualization="True" EnableRowVirtualization="True" SelectionChanged="grid_SelectionChanged"> 
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Time Stamp" Binding="{Binding StrTimeStamp, Mode=OneWay}" Width="Auto"/>
                    <DataGridTextColumn Header="Action" Binding="{Binding Action, Mode=OneWay}" Width="Auto"/>

            </DataGrid>

視圖模型:

    public ObservableCollection<LogData> LogList
    {
        get
        {
            if (logList == null)
            {
                logList = new ObservableCollection<LogData>();
            }
            return logList;
        }
        set
        {
            logList = value;
            OnPropertyChanged("LogList");
        }
    }

模型:

     public class LogData : INotifyPropertyChanged
{
    public LogData()
    {
    }
    private String timestamp = string.Empty;
    public String StrTimestamp
    {
        get
        {
            if (timestamp == null)
                return string.Empty;
            return timestamp ;
        }
        set
        {

            timestamp = value;
        }
    }
    public string Action
    {
       get;set;
    }

}

您可以創建自己的大小受限的可觀察集合類。 像這樣的事情應該讓你開始:

public class LimitedSizeObservableCollection<T> : INotifyCollectionChanged
{        
    private ObservableCollection<T> _collection;
    private bool _ignoreChange;

    public LimitedSizeObservableCollection(int capacity)
    {
        Capacity = capacity;
        _ignoreChange = false;
        _collection = new ObservableCollection<T>();
        _collection.CollectionChanged += _collection_CollectionChanged;
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public int Capacity {get;}

    public void Add(T item)
    {
        if(_collection.Count = Capacity)
        {
            _ignoreChange = true;
            _collection.RemoveAt(0);
            _ignoreChange = false;
        }
        _collection.Add(item);

    }

    private void _collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if(!_ignoreChange)
        {
            CollectionChanged?.Invoke(this, e);
        }
    }
}

當然,您可能需要公開更多方法,但我希望這足以讓您了解這個想法。

這個類可以很容易地完成:

public class LimitedSizeObservableCollection<T> : ObservableCollection<T>
{
    public int Capacity { get; }

    public LimitedSizeObservableCollection(int capacity)
    {
        Capacity = capacity;
    }

    public new void Add(T item)
    {
        if (Count >= Capacity)
        {
            this.RemoveAt(0);
        }
        base.Add(item);
    }
}

如果您希望它不應該添加到集合中超過 1000,您可以這樣做。

public ObservableCollection<LogData> LogList
{
    get
    {
        if (logList == null)
        {
            logList = new ObservableCollection<LogData>();
        }
        return logList;
    }
    set
    {
        if(LogList.Count < 1001)
        {
          logList = value;
          OnPropertyChanged("LogList");
        }
    }
}

或者您可以在添加超過 1000 個新條目時刪除舊條目

public ObservableCollection<LogData> LogList
{
    get
    {
        if (logList == null)
        {
            logList = new ObservableCollection<LogData>();
        }
        return logList;
    }
    set
    {
        if(LogList.Count < 1001)
        {
          logList = value;
          OnPropertyChanged("LogList");
        }
        else 
        {
           LogList.RemoveAt(0);
           logList = value;
           OnPropertyChanged("LogList");
        }
    }
}

我找到了另一種限制集合中元素數量的方法,而無需添加破壞與父類兼容性的“新”方法:

public class LimitedSizeObservableCollection<T> : ObservableCollection<T>
{
    public int Capacity { get; set; } = 0;

    protected override void InsertItem(int index, T item)
    {
        if (this.Capacity > 0 && this.Count >= this.Capacity)
        {
            throw new Exception(string.Format("The maximum number of items in the list  ({0}) has been reached, unable to add further items", this.Capacity));
        }
        else
        {
            base.InsertItem(index, item);
        }
    }
}

暫無
暫無

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

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