无法访问外部类型';的非静态成员;FormMain';通过嵌套类型';FormMain.ImageDe
本文关键字:FormMain ImageDe 嵌套类型 静态成员 外部 访问 类型 | 更新日期: 2023-09-27 18:00:48
我需要从MemoryStream输入更新C#WinForms PictureBox。我能够使用实现这一点
pictureBox.Image = new Bitmap(new MemoryStream(payload));
在解析流[RxThread()
]的线程中,但建议使用委托以避免不希望的影响。所以我实现了这个:
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#深度第二版中关于代表的章节,但这是我第一次真正尝试使用它。如何更改SetImage()
以便它可以访问pictureBox?
您应该将方法移动到表单类本身
你根本不需要单独上课。
此外,您可以使用内置的Action<byte[]>
委托,而不是创建自己的委托类型。
此外,直接打电话给代表对你没有任何好处;它仍将在后台线程上运行。
您需要调用BeginInvoke(new Action<byte[]>(this.SetImage), payload)
才能在UI线程上运行委托。
这里有两个问题:1,作为委托的函数可以而且应该在同一个类中(正如另一个答案所指出的),而不是自己的类。
其次,你没有正确地遵循上一个答案的建议。仅在委托中进行更新是不够的;您必须在控件上使用Invoke方法来运行委托,以便它在UI线程中运行。如果你以现在的方式运行委托,它仍然在同一个线程上,你仍然会遇到同样的问题。
您可以在setImage中引发事件,将数据和通知传递到主窗体。其他方法是使用InvokeRequied,将当前调用移动到创建的线程控件。