使用backgroundworker更新progressbar + clipboard.getimage() - WPF C# [英] Update progressbar + clipboard.getimage() with backgroundworker - WPF C#

查看:79
本文介绍了使用backgroundworker更新progressbar + clipboard.getimage() - WPF C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好



我的程序应该将文件夹中的某些Excel文件作为图像(SVG格式)导出到另一个文件夹中。这可以通过方法CopyAndSaveTo和ExportRangeAsImage来完成它们完成它们的工作。

在MainWindow上我有一个按钮,当它被点击时执行这两个功能。我希望通知点击此按钮的用户(进度条)这个过程有多远(复制+导出)。

我试图用BackgroundWorker实现它,只有当我发表评论时它才有效下面的代码(在方法ExportRangeAsImage中):



 Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage()); 
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file)+。svg);





否则我得到了以下错误消息(

从德语翻译):



在System.NullReferenceException中类型为System.Drawing.dll的异常已发生,但未在用户代码中处理。



附加信息:对象引用未设置为对象实例。



如果处理程序可用于此异常,程序可以继续安全运行。






以下是整个代码:

  private   void  UpdateDataOfLine1( object  sender,ExecutedRoutedEventArgs e)
{
string [] files = Directory.GetFiles(RootPath);

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true ;
worker.DoWork + = worker_DoWork;
worker.ProgressChanged + = worker_ProgressChanged;
worker.RunWorkerAsync();
}



void worker_DoWork( object sender,DoWorkEventArgs e)
{
string [] files = Directory.GetFiles(RootPath);

for int i = 0 ; i < files.Length; i ++)
{
if (files [i] .Contains( $)|| files [i] .Contains( )|| files [i] .Contains( Thumb))
{
continue ;
}

File.Copy(files [i],DestPath + Path.GetFileName(files [i]), true ) ;

string newFile = DestPath + Path.GetFileName(files [i]);

ExPortRangeAsImage(newFile);

(发件人 as BackgroundWorker).ReportProgress(i);
Thread.Sleep( 100 );
}
}



void worker_ProgressChanged(对象发​​件人,ProgressChangedEventArgs e)
{
Status.Value = e.ProgressPercentage;
}


public void ExPortRangeAsImage(< span class =code-keyword> string file)
{
var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

尝试
{
如果(文件。包含( BeispielDatei))
{
工作簿wb = ExcelApp.Workbooks 。打开文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}

else
{
工作簿wb = ExcelApp.Workbooks.Open(文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}
}

最后
{
Bitmap image = new 位图(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file)+ 。svg) ;

Marshal.ReleaseComObject(ExcelApp);
}
}





我的尝试:



  private   void  UpdateDataOfLine1 ( object  sender,ExecutedRoutedEventArgs e)
{
string [] files = Directory .GetFiles(ROOTPATH);

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true ;
worker.DoWork + = worker_DoWork;
worker.ProgressChanged + = worker_ProgressChanged;
worker.RunWorkerAsync();
}



void worker_DoWork( object sender,DoWorkEventArgs e)
{
string [] files = Directory.GetFiles(RootPath);

for int i = 0 ; i < files.Length; i ++)
{
if (files [i] .Contains( $)|| files [i] .Contains( )|| files [i] .Contains( Thumb))
{
continue ;
}

File.Copy(files [i],DestPath + Path.GetFileName(files [i]), true ) ;

string newFile = DestPath + Path.GetFileName(files [i]);

ExPortRangeAsImage(newFile);

(发件人 as BackgroundWorker).ReportProgress(i);
Thread.Sleep( 100 );
}
}



void worker_ProgressChanged(对象发​​件人,ProgressChangedEventArgs e)
{
Status.Value = e.ProgressPercentage;
}


public void ExPortRangeAsImage(< span class =code-keyword> string file)
{
var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

尝试
{
如果(文件。包含( BeispielDatei))
{
工作簿wb = ExcelApp.Workbooks 。打开文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}

else
{
工作簿wb = ExcelApp.Workbooks.Open(文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}
}

最后
{
Bitmap image = new 位图(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file)+ 。svg) ;

Marshal.ReleaseComObject(ExcelApp);
}
}







你能告诉我我在做什么吗错误或我如何实现它?

除了BackgroundWorker还有其他方法吗?



提前感谢您的帮助!

解决方案

)|| files [i] .Contains( )|| files [i] .Contains( Thumb))
{
continue ;
}

File.Copy(files [i], DestPath + Path.GetFileName(files [i]), true );

string newFile = DestPath + Path.GetFileName(files [i]);

ExPortRangeAsImage(newFile);

(sender as Backgroun dWorker).ReportProgress(ⅰ);
Thread.Sleep( 100 );
}
}



void worker_ProgressChanged(对象发​​件人,ProgressChangedEventArgs e)
{
Status.Value = e.ProgressPercentage;
}


public void ExPortRangeAsImage(< span class =code-keyword> string file)
{
var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

尝试
{
如果(文件。包含( BeispielDatei))
{
工作簿wb = ExcelApp.Workbooks 。打开文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}

else
{
工作簿wb = ExcelApp.Workbooks.Open(文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}
}

最后
{
Bitmap image = new 位图(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file)+ 。svg) ;

Marshal.ReleaseComObject(ExcelApp);
}
}





我的尝试:



  private   void  UpdateDataOfLine1 ( object  sender,ExecutedRoutedEventArgs e)
{
string [] files = Directory .GetFiles(ROOTPATH);

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true ;
worker.DoWork + = worker_DoWork;
worker.ProgressChanged + = worker_ProgressChanged;
worker.RunWorkerAsync();
}



void worker_DoWork( object sender,DoWorkEventArgs e)
{
string [] files = Directory.GetFiles(RootPath);

for int i = 0 ; i < files.Length; i ++)
{
if (files [i] .Contains(


)|| files [i] .Contains( )|| files [i ] .Contains( Thumb))
{
继续;
}

File.Copy(files [i],DestPath + Path.GetFileName(files [i]), true ) ;

string newFile = DestPath + Path.GetFileName(files [i]);

ExPortRangeAsImage(newFile);

(发件人 as BackgroundWorker).ReportProgress(i);
Thread.Sleep( 100 );
}
}



void worker_ProgressChanged(对象发​​件人,ProgressChangedEventArgs e)
{
Status.Value = e.ProgressPercentage;
}


public void ExPortRangeAsImage(< span class =code-keyword> string
file)
{
var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

尝试
{
如果(文件。包含( BeispielDatei))
{
工作簿wb = ExcelApp.Workbooks 。打开文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}

else
{
工作簿wb = ExcelApp.Workbooks.Open(文件);
工作表ws =(工作表)wb.Sheets [ 1 ];
范围= ws.Range [ A1:U35];
range.CopyPicture(XlPictureAppearance.xlScreen,XlCopyPictureFormat.xlBitmap);
wb.Close(SaveChanges: false );
Marshal.ReleaseComObject(wb);
}
}

最后
{
Bitmap image = new 位图(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file)+ 。svg) ;

Marshal.ReleaseComObject(ExcelApp);
}
}







你能告诉我我在做什么吗错误或我怎么能意识到这一点?

除了BackgroundWorker还有其他方法吗?



提前感谢您的帮助!


您的问题是您无法从多线程应用程序访问剪贴板。使用Thread类,您可以设置它是STA还是MTA ...但是我不认为可以使用backgroundworker类来做到这一点( c# - 如何将后台工作线程设置为单线程单元? - Stack Overflow [ ^ ])。



要使用Thread类设置STA,您可以执行以下操作:



线程t = 线程(AccessClipBoardHere()); 
t.SetApartmentState(ApartmentState.STA);
t.Start();


Hello

my program should export certain Excel files from a folder as an image (in SVG format) into another folder. This can be done by the Methods CopyAndSaveTo and ExportRangeAsImage and they do their job.
On the MainWindow I have a button that performs these two functions when it is clicked. I want the User who clicks on this button be informed (Progressbar) how far is this process (Copy + export).
I have tried to realise it using a BackgroundWorker and it works only if I comment the following code (in the Method ExportRangeAsImage):

Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");



Otherwise I get the following error message (
translated from German):

In System.NullReferenceException an exception of type "System.Drawing.dll" has occurred, but was this not processed in the user code.

Additional information: Object reference not set to an object instance.

If a handler is available for this exception, the program may continue to run safely.



Here is the whole code:

private void UpdateDataOfLine1(object sender, ExecutedRoutedEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerAsync();
        }



        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("$") || files[i].Contains("~") || files[i].Contains("Thumb"))
                {
                    continue;
                }

                File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true);

                string newFile = DestPath + Path.GetFileName(files[i]);

                ExPortRangeAsImage(newFile);

                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(100);
            }
        }



        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Status.Value = e.ProgressPercentage;
        }


        public void ExPortRangeAsImage(string file)
        {
            var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

            try
            {
                if (file.Contains("BeispielDatei"))
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }

                else
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }
            }

            finally
            {
                Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
                image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");

                Marshal.ReleaseComObject(ExcelApp);
            }
        }



What I have tried:

private void UpdateDataOfLine1(object sender, ExecutedRoutedEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerAsync();
        }



        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("$") || files[i].Contains("~") || files[i].Contains("Thumb"))
                {
                    continue;
                }

                File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true);

                string newFile = DestPath + Path.GetFileName(files[i]);

                ExPortRangeAsImage(newFile);

                (sender as BackgroundWorker).ReportProgress(i);
                Thread.Sleep(100);
            }
        }



        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Status.Value = e.ProgressPercentage;
        }


        public void ExPortRangeAsImage(string file)
        {
            var ExcelApp = new Microsoft.Office.Interop.Excel.Application();

            try
            {
                if (file.Contains("BeispielDatei"))
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }

                else
                {
                    Workbook wb = ExcelApp.Workbooks.Open(file);
                    Worksheet ws = (Worksheet)wb.Sheets[1];
                    Range range = ws.Range["A1:U35"];
                    range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
                    wb.Close(SaveChanges: false);
                    Marshal.ReleaseComObject(wb);
                }
            }

            finally
            {
                Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage());
                image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg");

                Marshal.ReleaseComObject(ExcelApp);
            }
        }




Can you show me what I'm doing wrong or how I can realize it?
Are there other ways than BackgroundWorker?

Thank you in advance for your help!

解决方案

") || files[i].Contains("~") || files[i].Contains("Thumb")) { continue; } File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true); string newFile = DestPath + Path.GetFileName(files[i]); ExPortRangeAsImage(newFile); (sender as BackgroundWorker).ReportProgress(i); Thread.Sleep(100); } } void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { Status.Value = e.ProgressPercentage; } public void ExPortRangeAsImage(string file) { var ExcelApp = new Microsoft.Office.Interop.Excel.Application(); try { if (file.Contains("BeispielDatei")) { Workbook wb = ExcelApp.Workbooks.Open(file); Worksheet ws = (Worksheet)wb.Sheets[1]; Range range = ws.Range["A1:U35"]; range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); wb.Close(SaveChanges: false); Marshal.ReleaseComObject(wb); } else { Workbook wb = ExcelApp.Workbooks.Open(file); Worksheet ws = (Worksheet)wb.Sheets[1]; Range range = ws.Range["A1:U35"]; range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); wb.Close(SaveChanges: false); Marshal.ReleaseComObject(wb); } } finally { Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage()); image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg"); Marshal.ReleaseComObject(ExcelApp); } }



What I have tried:

private void UpdateDataOfLine1(object sender, ExecutedRoutedEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerAsync();
        }



        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            string[] files = Directory.GetFiles(RootPath);

            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("


") || files[i].Contains("~") || files[i].Contains("Thumb")) { continue; } File.Copy(files[i], DestPath + Path.GetFileName(files[i]), true); string newFile = DestPath + Path.GetFileName(files[i]); ExPortRangeAsImage(newFile); (sender as BackgroundWorker).ReportProgress(i); Thread.Sleep(100); } } void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { Status.Value = e.ProgressPercentage; } public void ExPortRangeAsImage(string file) { var ExcelApp = new Microsoft.Office.Interop.Excel.Application(); try { if (file.Contains("BeispielDatei")) { Workbook wb = ExcelApp.Workbooks.Open(file); Worksheet ws = (Worksheet)wb.Sheets[1]; Range range = ws.Range["A1:U35"]; range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); wb.Close(SaveChanges: false); Marshal.ReleaseComObject(wb); } else { Workbook wb = ExcelApp.Workbooks.Open(file); Worksheet ws = (Worksheet)wb.Sheets[1]; Range range = ws.Range["A1:U35"]; range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap); wb.Close(SaveChanges: false); Marshal.ReleaseComObject(wb); } } finally { Bitmap image = new Bitmap(System.Windows.Forms.Clipboard.GetImage()); image.Save(ImagePath + Path.GetFileNameWithoutExtension(file) + ".svg"); Marshal.ReleaseComObject(ExcelApp); } }




Can you show me what I'm doing wrong or how I can realize it?
Are there other ways than BackgroundWorker?

Thank you in advance for your help!


Your issue is that you cannot access the clip board from a multi threaded application. Using the Thread class you can set whether it is STA or MTA...however i don't think it is possible to do that using the backgroundworker class (c# - How can I make a background worker thread set to Single Thread Apartment? - Stack Overflow[^]).

To set STA using Thread class you can do something like:

Thread t = new Thread(AccessClipBoardHere());
t.SetApartmentState(ApartmentState.STA);
t.Start();


这篇关于使用backgroundworker更新progressbar + clipboard.getimage() - WPF C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆