【问题标题】:Cannot add or insert the item MyFile in more than one place无法在多个位置添加或插入项目 MyFile
【发布时间】:2013-01-09 19:06:06
【问题描述】:

我正在构建播放 Wireshark 文件并使用 pcapdot.net 将数据包发送到网卡的应用程序。

在我的应用程序中,我获取根目录并仅添加过去 24 小时内的新文件。 首先,我将目录中的所有文件添加到List<string>,然后添加到我的ListView。 现在,在我的应用程序完成播放我的所有文件后,我想清除我的列表,清除我的 ListView 并再次搜索过去 24 小时内的 now 文件并添加到我的 ListView。 我的问题是在将文件再次添加到我的列表并尝试将文件添加到我的ListView 后,应用程序崩溃并出现错误无法在多个位置添加或插入项目“file.pcap”。您必须先将其从当前位置移除或克隆。

播放完我的文件后,我清理了 List、ListView 并再次添加文件并播放:

            lvFiles.Items.Clear();
            filesList.RemoveRange(0, filesList.Count - 1);
            addFiles();
            playFiles();

addFiles(); - 将 List 中的所有文件添加到我的 ListView:

private void addFiles()
{
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += new DoWorkEventHandler(
    (s3, e3) =>
    {
        filesList = SafeFileEnumerator.EnumerateFiles(pathToSearch, "*.pcap",
            SearchOption.AllDirectories).ToList();
    });

    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        (s3, e3) =>
        {
            if (filesList.Count != 0)
                AddFilesToListView(filesList);
        });

    backgroundWorker.RunWorkerAsync();
}

playFiles() - 在我的 ListView 中播放我的所有文件:

private void playFiles()
{
    lockButtons();
    string filePath = string.Empty;
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.DoWork += new DoWorkEventHandler(
    (s3, e3) =>
    {
        for (int i = 0; i < lvFiles.Items.Count && shouldContinue; i++)
        {
            this.Invoke((MethodInvoker)delegate
            {
                lvFiles.EnsureVisible(i);
                lvFiles.Items[i].Selected = true;
                lvFiles.Select();
                filePath = lvFiles.Items[i].Tag.ToString();
                toolStripStatusLabel.Text = string.Format("Current file: {0}", lvFiles.Items[i].Text);
            });

            PcapFile pcapFile = new PcapFile();
            pcapFile.sendQueue(filePath, adapter);
            this.Invoke((MethodInvoker)delegate { lvFiles.Items[i].Selected = false; });
        }
    });

将文件添加到我的 ListView:

private void addFileToListBox(string filePath, string duration)
{
    item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });
    item.Tag = new FileInfo(filePath).FullName;
    this.Invoke((MethodInvoker)delegate { lvFiles.Items.Add(item); });
}

也许“某人”仍然持有该文件?

【问题讨论】:

  • 显示一些代码。特别是您要添加到 ListView 并清除 ListView 的地方。
  • addFileToListBox 方法中的ListViewItem 命名为item 是在哪里声明的?

标签: c# winforms


【解决方案1】:

我很确定这可能是你的问题:

item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });

这会创建一个新对象,但仍然引用 item,从外观上看,它声明的范围比您预期的要大,可能是整个表单。

您需要使对象的范围与您将其添加到 ListView 的方法相同:

        private void addFileToListBox(string filePath, string duration)
        {
            ListViewItem item = new ListViewItem(new string[] { new FileInfo(filePath).Name, duration, "Waiting" });
            item.Tag = new FileInfo(filePath).FullName;
            this.Invoke((MethodInvoker)delegate { lvFiles.Items.Add(item); });
        }

如果您在更大的范围内声明了变量 item,那么每次创建新的 ListViewItem 时,您实际上仍然在列表视图中使用与第一次相同的项目。

虽然您没有显示声明 item 的位置,但您还需要删除在错误范围内声明它的行:

ListViewItem item; // <-- Delete me

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    相关资源
    最近更新 更多