我需要从MemoryStream输入更新C#WinForms PictureBox。 我能够使用
完成此任务pictureBox.Image = new Bitmap(new MemoryStream(payload));
在解析流[RxThread()
]的线程中但是advised to use a delegate以避免不良影响。
所以我实现了这个:
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));
}
}
但是在我尝试编译时会收到以下错误代码:
无法访问非静态成员 外部类型'FormMain'通过嵌套类型 'FormMain.ImageDelegateClass'
我确信将pictureBox设为静态是一个坏主意,因为它是WinForms生成的。
我知道修复可能很简单,但我对C#有点新意。
我已多次阅读Jon Skeets C#In Depth 2nd Edition中的代表章节,但这是我第一次尝试使用它。
如何更改SetImage()
以便它可以访问pictureBox?
答案 0 :(得分:3)
您应该将方法移动到表单类本身 您根本不需要单独的课程。
此外,您可以使用内置的Action<byte[]>
委托,而不是创建自己的委托类型。
另外,直接调用代表对你没有好处;它仍将在后台线程上运行。
您需要调用BeginInvoke(new Action<byte[]>(this.SetImage), payload)
来在UI线程上运行委托。
答案 1 :(得分:2)
这里有两个问题:1,你的作为委托的函数可以而且应该在同一个类中(正如其他答案所指出的那样)而不是它自己的类。
其次,您没有正确遵循上一个答案的建议。在委托中进行更新是不够的;您必须在控件上使用Invoke方法来运行委托,以便它在UI线程中运行。如果您按照现在的方式运行委托,它仍然在同一个线程上,您仍然会遇到同样的问题。
答案 2 :(得分:2)
您可以在setImage中引发事件,以将数据和通知传递给主窗体。其他方法是使用InvokeRequied,将当前调用移动到创建的线程控件。