无法通过嵌套类型“FormMain.ImageDelegateClass”访问外部类型“FormMain”的非静态成员

时间:2011-07-01 13:52:14

标签: c# .net winforms delegates compiler-errors

我需要从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?

3 个答案:

答案 0 :(得分:3)

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

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

另外,直接调用代表对你没有好处;它仍将在后台线程上运行。

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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