.net c# 限制 observablecollection 中的条目数
.net c# Limit number of entries in observablecollection
我有一个 WPF 应用程序,其中 UI 有一个列表框。列表框绑定了 ObservableCollection。日志 class 实现 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;
}
}
如果您希望它不应该添加到集合中超过 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");
}
}
}
您可以创建自己的大小受限的可观察集合 class。像这样的事情应该让你开始:
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);
}
}
}
当然,您可能需要公开更多的方法,但我希望这足以让您理解。
可以很容易地做到这一点 class:
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);
}
}
我找到了另一种方法来限制集合中元素的数量,而不添加破坏与父 类 兼容性的 "new" 方法:
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);
}
}
}
我有一个 WPF 应用程序,其中 UI 有一个列表框。列表框绑定了 ObservableCollection。日志 class 实现 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;
}
}
如果您希望它不应该添加到集合中超过 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");
}
}
}
您可以创建自己的大小受限的可观察集合 class。像这样的事情应该让你开始:
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);
}
}
}
当然,您可能需要公开更多的方法,但我希望这足以让您理解。
可以很容易地做到这一点 class:
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);
}
}
我找到了另一种方法来限制集合中元素的数量,而不添加破坏与父 类 兼容性的 "new" 方法:
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);
}
}
}