我有一个视图/视图模型,只显示"日志条目列表",最新项目位于顶部。用户还可以打开和关闭一些设置,以限制列表中显示哪些类型的日志条目。问题是随着日志项数量的增加,应用程序开始运行越来越慢,ItemsControl闪烁并闪烁。
这是VM代码(为简洁起见,删除了不相关的代码):
cb->buffer_end = cb->buffer + BUFFER_LENGTH;
A" IApplicationLogService"在记录消息时引发事件,并且此事件在上面的public class ApplicationLogViewModel
{
private readonly List<ApplicationLogEntry> _allLogEntries = new List<ApplicationLogEntry>();
// Bound to an ItemsControl in the view
public ICollectionView LogEntries { get; private set; }
// Ctr
public ApplicationLogModel(IApplicationLogService applicationLogService)
{
LogEntries = CollectionViewSource.GetDefaultView(_allLogEntries);
applicationLogService.MessageLogged += MessageLogged;
}
// Event handler to add new log entries to list
private void MessageLogged(object sender, ApplicationLogEntry logEntry)
{
var count = _allLogEntries.Count;
if (count >= 100)
{
_allLogEntries.RemoveAt(count - 1);
}
_allLogEntries.Insert(0, logEntry);
Dispatcher.CurrentDispatcher.Invoke(() => LogEntries.Refresh());
}
}
方法中处理,该方法只是将新项目添加到内部集合的开头(因此您可以获得列表顶部的最新项目) ,然后刷新集合视图(通过Dispatcher完成,因为UI线程上没有引发事件)。该代码还将列表限制为1000个项目,但在此之前很久就会出现问题 - 通常一旦有大约100个项目。
我省略了设置集合视图MessageLogged()
的代码(基于某些bool属性状态),因为即使使用Filter
也会发生减速。
据我所知,对Refresh()的调用会导致列表的完整更新/重绘,从而导致性能问题。所以问题是 - 我是否正确使用了集合视图,还是有更有效的方法来实现我想要做的事情?
答案 0 :(得分:1)
最简单的方法是将List<ApplicationLogEntry> _allLogEntries
更改为ObservableCollection<ApplicationLogEntry> _allLogEntries
并在其上使用数据绑定。用户界面会注意到集合中的每个更改都会自行删除/重新加载所需的内容。如果你需要一个关于数据绑定的小教程this one here帮助了我很多。