我有一个视图/视图模型,该视图仅显示“日志条目”的列表,而最新的项目位于顶部。用户还可以打开和关闭一些设置,以限制列表中显示哪种日志条目类型。问题在于,随着日志项数量的增加,应用程序开始运行的速度越来越慢,并且ItemsControl闪烁和闪烁。
这是VM代码(为简便起见,删除了不相关的代码):
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());
}
}
“ IApplicationLogService”会在记录消息时引发事件,并且该事件在上述MessageLogged()
方法中进行了处理,该方法只是将新项目添加到内部集合的开头(因此,最新的项目位于列表顶部),然后刷新集合视图(由于在UI线程上未引发事件,因此通过Dispatcher完成)。该代码还将列表限制为1000个项目,但此问题在此之前很久就很明显了-通常一次有大约100个项目。
我省略了用于设置集合视图Filter
(基于某些bool属性状态)的代码,因为即使使用,也会出现速度变慢的情况LogEntries.Filter = null
。
我了解对Refresh()的调用会导致列表的完整更新/重画,从而导致性能问题。因此,问题是-我是否正确使用了集合视图,还是有一种更有效的方法来实现我要执行的操作?
最简单的方法是将其更改List<ApplicationLogEntry> _allLogEntries
为ObservableCollection<ApplicationLogEntry> _allLogEntries
并在其上使用数据绑定。UI将自己注意到Collection中的所有更改,并将删除/重新加载所需的内容。如果您需要一些有关数据绑定的教程,那么这里的内容对我有很大帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句