-1

我有一个由 BackgroundWorker ProgressChanged 更新的 UI。它有一个进度条和一个列表视图,显示后台工作人员正在处理的每个项目的文件名。

如果它是一个新文件,我只想将一个项目添加到列表视图中,所以我尝试使用列表视图中的最后一个项目和当前文件名之间的比较。

但是,这会引发 TargetInvocation 错误。

void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

        var r = Enumerable.Empty<ListViewItem>();
        if (this.listView1.Items.Count > 0)
            r = this.listView1.Items.OfType<ListViewItem>();

        var last = r.LastOrDefault();

        if (last.Text != CurrentTrack.Name)
        {
            ListViewItem LVI = new ListViewItem(currentTrack.Name);
            LVI.SubItems.Add(keywords);
            LVI.SubItems.Add("Updated");
            listView1.Items.Add(LVI);
            listView1.TopItem = LVI;
            listView1.EnsureVisible(listView1.Items.Count - 1);
        }


        progressBar1.Value = e.ProgressPercentage;
        lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
    }

有可能实现这一目标吗?

4

2 回答 2

0

这会引发同样的错误吗?

    void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ListViewItem last = null;
        if (this.listView1.Items.Count > 0)
        {
            last = this.listView1.Items[listView1.Items.Count - 1];
        }
        if (last == null || last.Text != CurrentTrack.Name)
        {
            ListViewItem LVI = new ListViewItem(currentTrack.Name);
            LVI.SubItems.Add(keywords);
            LVI.SubItems.Add("Updated");
            listView1.Items.Add(LVI);
            listView1.TopItem = LVI;
            listView1.EnsureVisible(listView1.Items.Count - 1);
        }

        progressBar1.Value = e.ProgressPercentage;
        lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
    }
于 2013-05-07T12:54:34.890 回答
0

您需要在 UI 线程上执行 UI 更改。这可以使用以下代码来实现:

frmMain()
{
    Worker_ProgressChanged = new Worker_ProgressChanged_Delegate(m_oWorker_ProgressChanged);
}

delegate void Worker_ProgressChanged_Delegate(object sender, ProgressChangedEventArgs e);
Worker_ProgressChanged_Delegate Worker_ProcessChanged;
void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (this.InvokeRequired)
    {
        this.Invoke(Worker_ProgressChanged, sender, e);
    }
    else
    {
        ... Add list items etc.
    }

如果工作线程调用此方法,则 InvokeRequired 将为真。然后表单将使用其线程(UI 线程)调用相同的方法。这次 InvokeRequired 为 false,函数在正确的线程上执行。

编辑:根据评论将添加列表项移动到其他块

于 2013-05-07T09:36:10.080 回答