Не удается получить доступ к нестатическому члену внешнего типа FormMain через вложенный тип FormMain.ImageDelegateClass - PullRequest
0 голосов
/ 01 июля 2011

Мне нужно обновить C # WinForms PictureBox из ввода MemoryStream.Я смог сделать это, используя

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 # In Depth 2nd Edition несколько раз, но я впервые попробовал ее использовать.Как я могу изменить SetImage(), чтобы он мог получить доступ к pictureBox?

Ответы [ 3 ]

3 голосов
/ 01 июля 2011

Вы должны переместить метод в сам класс формы.
Вам вообще не нужен отдельный класс.

Также вы можете использовать встроенный делегат Action<byte[]> вместо созданияваш собственный тип делегата.

Кроме того, просто вызов делегата напрямую не поможет;он все равно будет работать в фоновом потоке.

Вам нужно вызвать BeginInvoke(new Action<byte[]>(this.SetImage), payload), чтобы запустить делегат в потоке пользовательского интерфейса.

2 голосов
/ 01 июля 2011

Вы можете вызвать событие в setImage для передачи данных и уведомлений в основную форму. Другой способ - использовать InvokeRequied, чтобы переместить текущий вызов в созданный элемент управления потоком.

2 голосов
/ 01 июля 2011

Здесь две проблемы: 1, ваша функция, которая будет делегатом, может и должна быть в том же классе (как указывает другой ответ) вместо собственного класса.

Во-вторых, вы не правильно следуете советам предыдущего ответа. Недостаточно сделать обновление в делегате; Вы должны использовать метод Invoke в вашем элементе управления для запуска делегата, чтобы он выполнялся в потоке пользовательского интерфейса. Если вы выполняете делегат так, как вы это делаете сейчас, он все еще в том же потоке, и у вас все равно будет та же проблема.

...