代码如下:(实现listview导出)
private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)//要做的事
 {
 BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender); ExportToExcel2(worker,e);
 }
 public: void ExportToExcel2(BackgroundWorker^ worker, DoWorkEventArgs ^ e)
  {
  String ^saveFileName = m_saveFileName;
  ListView ^pListView = listView1;
  Microsoft::Office::Interop::Excel::Application ^xlApp = gcnew Microsoft::Office::Interop::Excel::Application();
  if (xlApp == nullptr)
  {
  MessageBox::Show("无法创建Excel对象,可能您的机器未安装Excel");
  return;
  }   Microsoft::Office::Interop::Excel::Workbooks ^workbooks = xlApp->Workbooks;
  Microsoft::Office::Interop::Excel::Workbook ^workbook = workbooks->Add(true);
  Microsoft::Office::Interop::Excel::Worksheet ^worksheet = (Microsoft::Office::Interop::Excel::Worksheet^)workbook->Worksheets[1];
  xlApp->Visible = false;
  //填充列
  for (int i = 0; i < pListView->Columns->Count; i++)
  {
  worksheet->Cells[1, i + 1] = pListView->Columns[i]->Text->ToString();
  ((Microsoft::Office::Interop::Excel::Range^)worksheet->Cells[1, i + 1])->Font->Bold = true;
  }
  worksheet->Columns->EntireColumn->AutoFit();//列宽自适应
  //填充数据(这里分了两种情况,1:lv带CheckedBox,2:不带CheckedBox)   int  num = 0;
  //带CheckedBoxes
  if (pListView->CheckBoxes == true)
  {
  int tmpCnt = 0;
  for (int i = 0; i < pListView->Items->Count; i++)
  {
  if (pListView->Items[i]->Checked == true)
  {
  for (int j = 0; j < pListView->Columns->Count; j++)
  {
  if (j == 0)
  {
  worksheet->Cells[2 + tmpCnt, j + 1] = pListView->Items[i]->Text->ToString();
  ((Microsoft::Office::Interop::Excel::Range ^)worksheet->Cells[2 + tmpCnt, j + 1])->HorizontalAlignment = Microsoft::Office::Interop::Excel::XlHAlign::xlHAlignLeft;
  }
  else
  {
  worksheet->Cells[2 + tmpCnt, j + 1] = pListView->Items[i]->SubItems[j]->Text->ToString();
  ((Microsoft::Office::Interop::Excel::Range^)worksheet->Cells[2 + tmpCnt, j + 1])->HorizontalAlignment = Microsoft::Office::Interop::Excel::XlHAlign::xlHAlignLeft;
  }
  }
  tmpCnt++;
  }
  }
  }
  else //不带Checkedboxe
  {
  for (int i = 0; i < pListView->Items->Count; i++)
  {
  for (int j = 0; j < pListView->Columns->Count; j++)
  {
  if (j == 0)
  {
  worksheet->Cells[2 + i, j + 1] = pListView->Items[i]->Text->ToString();//这里提示不能访问,错误。
  ((Microsoft::Office::Interop::Excel::Range^)worksheet->Cells[2 + i, j + 1])->HorizontalAlignment = Microsoft::Office::Interop::Excel::XlHAlign::xlHAlignLeft;
  }
  else
  {
  worksheet->Cells[2 + i, j + 1] = pListView->Items[i]->SubItems[j]->Text->ToString();
  ((Microsoft::Office::Interop::Excel::Range^)worksheet->Cells[2 + i, j + 1])->HorizontalAlignment = Microsoft::Office::Interop::Excel::XlHAlign::xlHAlignLeft;   num++;   int percentComplete = (int)(((float)num/ (long)(pListView->Items->Count *pListView->Columns->Count))*100);   if ( percentComplete == 100)
  {
  int dd = 0;
  }
  if ( percentComplete > highestPercentageReached )
  {
  highestPercentageReached = percentComplete;
  worker->ReportProgress( percentComplete );
  }   }   }
  }
  }
  Object ^missing = System::Reflection::Missing::Value;
  try
  {
  workbook->Saved = true;
  workbook->SaveAs(saveFileName, Microsoft::Office::Interop::Excel::XlFileFormat::xlXMLSpreadsheet, missing, missing, false, false, Microsoft::Office::Interop::Excel::XlSaveAsAccessMode::xlNoChange, missing, missing, missing, missing, missing);
  }
  catch (Exception ^e1)
  {
  MessageBox::Show("导出文件时出错,文件可能正被打开!\n" + e1->Message);
  }
  finally
  {
  xlApp->Quit();
  System::GC::Collect();
  }   MessageBox::Show("导出Excle成功!");   }

解决方案 »

  1.   

    worker.DoWork += ...  \\这里面的委托还是异步执行的。
    worker.ProgressChanged +=  ... \\这里的委托才同步到UI线程了。
      

  2.   

    说的在明白点,不太懂。
    ProgressChanged 一般是和
    bw.ProgressChanged += new ProgressChangedEventHandler(bw_Doing);
    doing相联系的改变进度条的
      

  3.   


    UP
    UP 
     
      

  4.   

    DoWork里做的事情,其实是放在一个独立的线程(非UI线程)执行你的工作任务,这个时候如果你要访问由UI线程创建的控件,如ListView的对象,就会报错.
    但为什么ProgressChanged里又可以操作UI控件呢?
    那是因为ProgressChanged被触发时,已经回到UI线程了,你可以更新你的进度条显示.有兴趣可以看一下ReportProgress的代码
    public void ReportProgress(int percentProgress, object userState)
    {
        if (!this.WorkerReportsProgress)
        {
            throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntReportProgress"));
        }
        ProgressChangedEventArgs arg = new ProgressChangedEventArgs(percentProgress, userState);
        if (this.asyncOperation != null)
        {
            this.asyncOperation.Post(this.progressReporter, arg);
        }
        else
        {
            this.progressReporter(arg);
        }
    }asyncOperation 是一个 AsyncOperation的对象,通过Post方法调用,可以改变线程的上下文,将第一个委托(也是ProgressChanged的事件处理方法)转放到UI线程中执行.
    想了解更多,可以参考
    实现基于事件的异步模式
      

  5.   

    BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。注意: 
    您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。BackgroundWorker 事件不跨 AppDomain 边界进行封送处理。请不要使用 BackgroundWorker 组件在多个 AppDomain 中执行多线程操作。
     如果后台操作需要参数,请在调用 RunWorkerAsync 时给出参数。在 DoWork 事件处理程序内部,可以从 DoWorkEventArgs..::.Argument 属性中提取该参数。有关 BackgroundWorker 的更多信息,请参见 如何:在后台运行操作。MSDN说明了里面不能放UI控件。
      

  6.   

    this.threadStart.BeginInvoke(argument, null, null);   
    你的Dowork绑定的方法是这样进行的,在另一个线程中,在这个线程中不能直接访问UI的控件你必须在你Dowork绑定的方法中,调用ReportProgress 来汇报进度,修改UI。如果不想通过这个修改,必须把要处理的消息发给UI进行处理LZ没有了解BackgroundWork的用法。
    http://blog.csdn.net/cc_net/archive/2009/11/10/4796109.aspx