【问题标题】:.net c# Limit number of entries in observablecollection.net c#限制observablecollection中的条目数
【发布时间】:2018-05-01 18:10:17
【问题描述】:

我有一个 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;
    }

}

【问题讨论】:

  • 可能绑定到 CollectionChanged 事件并删除除最近的 1000 之外的任何项目。

标签: c# data-binding observablecollection


【解决方案1】:

这个类很容易做到:

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);
    }
}

【讨论】:

    【解决方案2】:

    您可以创建自己的大小有限的可观察集合类。这样的事情应该可以帮助您入门:

    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);
            }
        }
    }
    

    当然,您可能需要公开更多方法,但我希望这足以让您了解这个想法。

    【讨论】:

    • 稍作修改我就可以完成这项工作!感谢您的建议
    • 很高兴为您提供帮助 :-)
    【解决方案3】:

    如果你希望它不应该添加到超过 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");
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我找到了另一种限制集合中元素数量的方法,而不添加破坏与父类兼容性的“新”方法:

      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);
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-12-27
        • 2021-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多