ListView虚拟化需要一个有效的ListViewItem,由RetrieveVirtualItem事件或OnRetr
本文关键字:ListViewItem RetrieveVirtualItem OnRetr 事件 有效 一个 虚拟化 ListView | 更新日期: 2023-09-27 18:09:03
有人可以清除我在哪里我错了在这段代码…我知道listView1_RetrieveVirtualItem
方法有问题,但我无法纠正。我得到这个错误:
下面是我的代码:ListView虚拟化需要一个有效的ListViewItem由RetrieveVirtualItem事件或OnRetrieveVirtualItem方法提供。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_fileInfoCollection = new Queue<ListViewFileInfo>();
}
private void GetFileInformation(string drive)
{
_fileInfoCollection.Clear();
var directory = new DirectoryInfo(drive);
var files = directory.GetFiles("*.*", SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
_fileInfoCollection.Enqueue(new ListViewFileInfo() { FileName = file.Name, FilePath = file.FullName });
}
}
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
if (_fileInfoCollection.Count > 0)
{
ListViewFileInfo fileInfo = _fileInfoCollection.Dequeue();
var listViewItem = new ListViewItem();
listViewItem.Text = fileInfo.FileName;
var listViewSubItem = new ListViewItem.ListViewSubItem();
listViewSubItem.Text = fileInfo.FilePath;
listViewItem.SubItems.Add(listViewSubItem);
e.Item = listViewItem;
}
}
private void comboBoxDrive_SelectedIndexChanged(object sender, EventArgs e)
{
GetFileInformation(comboBoxDrive.Text);
}
private Queue<ListViewFileInfo> _fileInfoCollection;
}
使用ListView虚拟模式的代码仍然缺少一些重要信息。首先,我们需要将value设置为ListView的VirtualListSize属性。其次,我们需要设置一个缓存值来正确检索listtitem。
我们应该记住RetrieveVirtualItem事件总是要求返回一个ListViewItem。
你可以参考这里:http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode%28v=vs.90%29.aspx
我已经修改了你的代码基础上我的假设,你可以修改它按照你的想法。希望对你有所帮助。
public partial class Form1 : Form
{
private ListViewItem[] myCache; //array to cache items for the virtual list
private int firstItem; //stores the index of the first item in the cache
public Form1()
{
InitializeComponent();
_fileInfoCollection = new Queue<ListViewFileInfo>();
}
private void GetFileInformation(string drive)
{
_fileInfoCollection.Clear();
var directory = new DirectoryInfo(drive);
var files = directory.GetFiles("*.*", SearchOption.TopDirectoryOnly);
myCache = new ListViewItem[files.Length];
int temp = 0;
foreach (var file in files)
{
_fileInfoCollection.Enqueue(new ListViewFileInfo() { FileName = file.Name, FilePath = file.FullName });
ListViewFileInfo fileInfo = _fileInfoCollection.Dequeue();
var listViewItem = new ListViewItem();
listViewItem.Text = fileInfo.FileName;
var listViewSubItem = new ListViewItem.ListViewSubItem();
listViewSubItem.Text = fileInfo.FilePath;
listViewItem.SubItems.Add(listViewSubItem);
myCache[temp] = listViewItem;
temp++;
}
listView1.VirtualListSize = myCache.Length;
}
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
if (myCache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + myCache.Length)
{
//A cache hit, so get the ListViewItem from the cache instead of making a new one.
e.Item = myCache[e.ItemIndex - firstItem];
}
else
{
//A cache miss, so create a new ListViewItem and pass it back.
e.Item = new ListViewItem();
}
}
private void comboBoxDrive_SelectedIndexChanged(object sender, EventArgs e)
{
GetFileInformation(comboBoxDrive.Text);
}
private Queue<ListViewFileInfo> _fileInfoCollection;
}
我遇到过这个问题几次,对于任何像我一样使用ObjectListView (FastObjectListView)开源库的人,或者只是使用带有数据源的虚拟ListView,我发现问题不是列表或数据本身,而是数据的来源。
当使用虚拟列表时,很难从错误中诊断出来,但是当我将FastObjectListView更改为ObjectListView(基本上删除了虚拟功能)时,我能够看到导致异常的实际错误,并且曾经存在的视图不再存在于我的实体框架模型上。
希望这能帮助到一些人,因为它让我抓耳挠脑,谷歌出了那个无用的错误信息。
完整代码如下:
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listView1 = new System.Windows.Forms.ListView();
this.columnHeaderIndex = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderInformation = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.comboBoxDrive = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// listView1
//
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeaderIndex,
this.columnHeaderInformation});
this.listView1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.listView1.Location = new System.Drawing.Point(0, 24);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(551, 249);
this.listView1.TabIndex = 0;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
this.listView1.VirtualListSize = 500;
this.listView1.VirtualMode = true;
this.listView1.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.listView1_RetrieveVirtualItem);
//
// columnHeaderIndex
//
this.columnHeaderIndex.Text = "Index";
//
// columnHeaderInformation
//
this.columnHeaderInformation.Text = "Information";
this.columnHeaderInformation.Width = 400;
//
// comboBoxDrive
//
this.comboBoxDrive.FormattingEnabled = true;
this.comboBoxDrive.Items.AddRange(new object[] {
"C:",
"D:"});
this.comboBoxDrive.Location = new System.Drawing.Point(-4, 0);
this.comboBoxDrive.Name = "comboBoxDrive";
this.comboBoxDrive.Size = new System.Drawing.Size(121, 21);
this.comboBoxDrive.TabIndex = 2;
this.comboBoxDrive.SelectedIndexChanged += new System.EventHandler(this.comboBoxDrive_SelectedIndexChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(551, 273);
this.Controls.Add(this.comboBoxDrive);
this.Controls.Add(this.listView1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ColumnHeader columnHeaderInformation;
private System.Windows.Forms.ColumnHeader columnHeaderIndex;
private ComboBox comboBoxDrive;
我的代码中还遗漏了什么吗?拜托!检查它。我很想看看输出