无法访问外部类型';的非静态成员;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?

无法访问外部类型';的非静态成员;FormMain';通过嵌套类型';FormMain.ImageDe

您应该将方法移动到表单类本身
你根本不需要单独上课。

此外,您可以使用内置的Action<byte[]>委托,而不是创建自己的委托类型。

此外,直接打电话给代表对你没有任何好处;它仍将在后台线程上运行。

您需要调用BeginInvoke(new Action<byte[]>(this.SetImage), payload)才能在UI线程上运行委托。

这里有两个问题:1,作为委托的函数可以而且应该在同一个类中(正如另一个答案所指出的),而不是自己的类。

其次,你没有正确地遵循上一个答案的建议。仅在委托中进行更新是不够的;您必须在控件上使用Invoke方法来运行委托,以便它在UI线程中运行。如果你以现在的方式运行委托,它仍然在同一个线程上,你仍然会遇到同样的问题。

您可以在setImage中引发事件,将数据和通知传递到主窗体。其他方法是使用InvokeRequied,将当前调用移动到创建的线程控件。