0

嗨,有一个名为 Dlist 的主表单中的 ListView,我有一个后台工作人员来下载文件,在后台工作人员中,我如何在主表单列表视图中编辑子项“进度”?

我的代码:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, e) => WorkerDoWork(link, savepath,Dlist);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progress_complete);
worker.ProgressChanged += new ProgressChangedEventHandler(progress_changed);
worker.RunWorkerAsync();


rivate void WorkerDoWork(string link, string savepath, ListView Dlist)
    {
        // Start Download
        Uri url = new Uri(link);
        System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
        System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
        response.Close();
        Int64 iSize = response.ContentLength;
        Int64 iRunningByteTotal = 0;
        using (System.Net.WebClient client = new System.Net.WebClient())
        {
            using (System.IO.Stream streamRemote = client.OpenRead(new Uri(link)))
            {
                using (Stream streamLocal = new FileStream(savepath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    int iByteSize = 0;
                    byte[] byteBuffer = new byte[256];
                    while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
                    {
                        streamLocal.Write(byteBuffer, 0, iByteSize);
                        iRunningByteTotal += iByteSize;
                        double dIndex = (double)(iRunningByteTotal);
                        double dTotal = (double)byteBuffer.Length;
                        double dProgressPercentage = (dIndex / dTotal);
                        int iProgressPercentage = (int)(dProgressPercentage * 100);
                        //Dlist.Items[Dlist.Items.IndexOfKey(fileName)].SubItems[2].Text = iProgressPercentage.ToString();
                    }
                    streamLocal.Close();
                }
                streamRemote.Close();
            }
        }
    }

这一行 (//Dlist.Items[Dlist.Items.IndexOfKey(fileName)].SubItems[2].Text = iProgressPercentage.ToString();) 是为了更新列表视图,但我一直在跨线程。

4

3 回答 3

0

我不必担心必须使用委托并从 Do_Work 方法调用它,而是将BackgroundWorker.WorkerReportsProgress设置为 true 并订阅BackgroundWorker.ProgressChanged事件。处理该事件将在 UI 线程上发生,您可以通过从参数中提取进度并从那里更新您的 ListView 来使用报告的进度(从 Do_Work 方法调用)。

于 2012-04-19T11:42:07.563 回答
0

为什么不使用 BackgroundWorker.ReportProgress 方法(参见示例部分)?

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

于 2012-04-19T11:40:27.050 回答
0

因为 backgroundworker 确实是一个不同的线程,与 UI 线程分开,您需要检查该用户控件是否需要调用。下面是我使用 listView1 作为 Dlist 的一些源代码。

    delegate void SetListViewItemCallBack(ListViewItem Item);
    private void AddListViewItem(ListViewItem Item)
    {
        if (this.listView1.InvokeRequired)
        {
            SetListViewItemCallBack d = new SetListViewItemCallBack(AddListViewItem);
            this.Invoke(d, new object[] { Item });
        }
        else
        {
            this.listView1.Items.Add(Item);
        }
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        DataSet dsInfo = // whatever you want..
        for (int i = 0; i < dsInfo.Tables[0].Rows.Count; i++)
        {
            ListViewItem li = new ListViewItem();
            li.Text = dsInfo.Tables[0].Rows[i]["AXT_Tag"].ToString();
            li.Tag = dsInfo.Tables[0].Rows[i]["AXT_ID"].ToString();
            AddListViewItem(li);
        }
    }
于 2012-04-19T11:35:59.237 回答