Using MSChart COM Component in VB.net
"Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.".
I think I understand what it means, but how do I fix it?
Mike Harsh wrote:
This sounds like a known issue with the Visual Studio hosting process. The Visual Studio hosting process starts up a main thread and then creates a new UI thread that the application is run on. Some ActiveX controls do not support running on a UI thread that is not the main thread, hence this exception is being thrown.
The workaround is to disable the Visual Studio hosting process. To do this, open the project proeprty designer and selet the Debug tab. Then uncheck the "Enable the Visual Studio hosting process" checkbox.
VS host gives a performance boost to the F5 scenario and also enables the debug in security zone functionality. You will not be able to access these features if VS host is disabled.
Hope this helps.
- mike
I'm having the same problem. I disabled the hosting process and ran my program. In my case the alternate thread is started by a timer or is a timer thread updatting a listview control.
I ran the program with for a couple of passes and it worked - then it failed with the same error.
The host process is definitely turned off.
I've tried fooling it and it doesn't seem to be foolable.
Dealing with this requires a delegate routine and is needed at runtime regardless of whether a host process is present or not.
I do have code but the code is rather esoteric and I don't think it's too illustrative. :(
Good luck!
Joel
I found the error actually occurs in the line:
IDataObject drawing = (IDataObject)(Clipboard.GetDataObject());
Pasting the data into Paint after a failure worked. To get arround this, I created a small application that copied the contents from the clipboard, then proceded to print it. This code worked fine for me. I hope this helps!
Note that I had no such problems with VB 2003.
using System.Runtime.InteropServices;
...
//copy the chart bitmap to the clipboard
MSChart1.EditCopy();
Application.DoEvents();
//open the clipboard
if (Win32ClipboardAPI.OpenClipboard(IntPtr.Zero))
{
//check that it has recognized the bitmap
if (Win32ClipboardAPI.IsClipboardFormatAvailable(Win32ClipboardAPI.CF_BITMAP))
{
//Get the pointer for the current Clipboard Data
IntPtr bmptr = Win32ClipboardAPI.GetClipboardData(Win32ClipboardAPI.CF_BITMAP);
if (bmptr != IntPtr.Zero)
{
//retrieve the bitmap
Bitmap chartCapture = Bitmap.FromHbitmap(bmptr);
.....
//tidy up
chartCapture.Dispose();
}
}
//Close the clipboard and release unused resources
Win32ClipboardAPI.CloseClipboard();
}
private class Win32ClipboardAPI
{
public const uint CF_BITMAP = 2;
[DllImport("user32.dll")]
public static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll")]
public static extern IntPtr GetClipboardData(uint uFormat);
[DllImport("user32.dll")]
public static extern bool CloseClipboard();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool IsClipboardFormatAvailable(uint format);
}