I need to update a C# WinForms PictureBox from a MemoryStream input. I was able to accomplish this using
pictureBox.Image = new Bitmap(new MemoryStream(payload));
in the thread that parses the stream [RxThread()
] but was advised to use a delegate to avoid undesirable effects.
So I've implemented this:
private void RxThread()
{
...
var imageDelegateClass = new ImageDelegateClass();
var imageDelegate = new ImageDelegate(imageDelegateClass.SetImage);
imageDelegate(payload);
...
}
delegate void ImageDelegate(byte[] payload);
class ImageDelegateClass
{
public void SetImage(byte[] payload)
{
pictureBox.Image = new Bitmap(new MemoryStream(payload));
}
}
but get the following error code when I try to compile:
Cannot access 开发者_JS百科a non-static member of outer type 'FormMain' via nested type 'FormMain.ImageDelegateClass'
I am sure its a bad idea to make pictureBox static since it is WinForms generated.
I know the repair is probably simple but I am a bit new to C#.
I have read the chapter on Delegates in Jon Skeets C# In Depth 2nd Edition multiple times but this is the first time I've actually tried to use one.
How can I change SetImage()
so it can access pictureBox?
You should move the method to the form class itself.
You don't need a separate class at all.
Also, you can use the built-in Action<byte[]>
delegate instead of creating your own delegate type.
Also, just calling the the delegate directly doesn't do you any good; it will still run on the background thread.
You need to call BeginInvoke(new Action<byte[]>(this.SetImage), payload)
to run the delegate on the UI thread.
Two problems here: 1, your function that will be the delegate can and should be in the same class (as the other answer points out) instead of a class of its own.
Second, you are not following the advice of the previous answer correctly. It is not enough to make the update in a delegate; you have to use the Invoke method on your control to run the delegate so it runs in the UI thread. If you run the delegate the way you are doing now it is still on the same thread and you will still have the same problem.
You can raise event in setImage to pass data and notification to main form. Other way is to use InvokeRequied, to move current call to the thread control was created.
精彩评论