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虚拟化需要一个有效的ListViewItem,由RetrieveVirtualItem事件或OnRetr

使用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;

我的代码中还遗漏了什么吗?拜托!检查它。我很想看看输出