我的问题是我需要在WPF中向Listview添加很多项目。在WinForms中,您只需使用BeginUpdate()
方法,添加所有内容,最后使用EndUpdate()
方法。
那么,在添加每个项目然后一次性绘制所有项目之前,如何在WPF Listview中停止绘图?
foreach (FilePaths filePath in directoryPath.GetFilePaths())
{
GetFileListViewItem(filePath);
}
在这个GetFileListViewItem
方法中,我将项目添加到listview。
private void GetFileListViewItem(FilePaths filePath)
{
string ext = GetExtension(filePath.GetPath());
string fileName = GetFileNameWithoutExtension(filePath.GetPath());
string type = "";
if (ext != "")
{
type = ext.ToUpper().Substring(1) + " File";
}
else
{
type = "Unknown";
}
fileListView.Items.Add(new FileListItem
{
Name = fileName,
Type = type
});
}
答案 0 :(得分:1)
我有一个类似的问题并通过延迟添加解决了它,我编码自定义添加,例如500毫秒延迟,如果我在这个时间有更多的添加,所以我等待下一个500毫秒。 这会导致您经常添加太多项目,因此只会在您的表单中进行单一渲染。
答案 1 :(得分:1)
我认为,在处理WPF时,最好远离WinForms心态,直接操纵代码背后的控件。 WPF最大的优势之一是其数据绑定功能。
ListView
控件(从它出现的ItemsControl
继承的任何内容)实现了UI虚拟化。从此链接:WPF: Data Virtualization
当WPF ItemsControl绑定到大型集合数据源时,启用了UI虚拟化,控件将仅为实际可见的项目(以及上面和下面的几个)创建可视容器。这通常只是整个系列的一小部分。当用户滚动时,在项目变得可见时创建新的可视容器,并且当项目不再可见时处置旧容器。启用容器回收后,它将重用可视容器而不是创建和处理,从而避免了对象实例化和垃圾回收开销。
UI虚拟化意味着控件可以绑定到大型集合,而不会因可视容器而导致大量内存占用。但是,由于集合中的实际数据对象,可能存在大量内存占用。
但是,根据对此question的回答,当数据将ItemsSource
属性绑定到集合时,虚拟化似乎只会启动。因此,似乎直接向ListView
添加项目正在阻止虚拟化。
答案 2 :(得分:0)
尝试在Dispatcher.BeginInvoke中执行优先级低于DispatcherPriority.Render的代码
这应该在渲染之前添加所有项目。
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, (Action)delegate
{
GetFileListViewItem(filePath);
});
答案 3 :(得分:0)
使用DataBinding
将ListVies的DataSource绑定到MyFileListItem
神奇的速度将会发生
我认为直接打破虚拟化
它确实绘制了一次,但是您正在生成多个UI更改通知
这只是一个数据绑定
如果要添加和删除,请使用ObservableCollection
如果值将在FileListItem中更改,那么您需要实现iNotifyProperty已更改
private List<FileListItem> myFileListItems;
public List<FileListItem> MyFileListItems
{
get
{
if (myFileListItems == null)
{
myFileLinstItems = new List<FileListItem>();
foreach (FilePaths filePath in directoryPath.GetFilePaths())
{
string ext = GetExtension(filePath.GetPath());
if (String.IsNullOrEmpty(ext)
ext = "Unknown";
else
ext = ext.ToUpper().Substring(1) + " File";
myFileListItems.Add(new FileListItem
{
Name = GetFileNameWithoutExtension(filePath.GetPath());,
Type = ext
});
}
}
return myFileListItems;
}
}