Модифицировать структуру, переданную в обработчик событий? - PullRequest
0 голосов
/ 12 марта 2012

Это, кажется, довольно простая концепция, которую я не понимаю.

При написании оболочки .NET для драйвера клавиатуры я транслирую событие для каждой нажатой клавиши, вот так (упрощеннокод ниже):

// The event handler applications can subscribe to on each key press
public event EventHandler<KeyPressedEventArgs> OnKeyPressed;
// I believe this is the only instance that exists, and we just keep passing this around
Stroke stroke = new Stroke();

private void DriverCallback(ref Stroke stroke...)
{
    if (OnKeyPressed != null)
    {
        // Give the subscriber a chance to process/modify the keystroke
        OnKeyPressed(this, new KeyPressedEventArgs(ref stroke) );
    }

    // Forward the keystroke to the OS
    InterceptionDriver.Send(context, device, ref stroke, 1);
}

Ход - это struct, который содержит код сканирования для нажатой клавиши и состояние.

В вышеприведенном коде, поскольку я передаю структуру типа значения по ссылке, любые изменения, внесенные в структуру, будут «запоминаться» при передаче в ОС (так что нажатые клавиши могут быть перехвачены и изменены).Так что все в порядке.

Но как мне разрешить подписчикам моего OnKeyPressed события изменять struct Stroke?

Следующее не работает:

public class KeyPressedEventArgs : EventArgs
{
    // I thought making it a nullable type might also make it a reference type..?
    public Stroke? stroke;

    public KeyPressedEventArgs(ref Stroke stroke)
    {
        this.stroke = stroke;
    }
}

// Other application modifying the keystroke

void interceptor_OnKeyPressed(object sender, KeyPressedEventArgs e)
{
    if (e.stroke.Value.Key.Code == 0x3f) // if pressed key is F5
    {
        // Doesn't really modify the struct I want because it's a value-type copy?
        e.stroke.Value.Key.Code = 0x3c; // change the key to F2
    }
}

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Передача вашей структуры в конструктор KeyPressedEventArg передается по ссылке, но это так, каждый раз при изменении переменной обводки она передается по значению. Если вы продолжаете передавать эту структуру по ref, вы можете рассмотреть возможность создания для нее класса-оболочки. Лучшее дизайнерское решение в долгосрочной перспективе.

1 голос
/ 12 марта 2012

Что-то вроде этого может помочь:

if (OnKeyPressed != null)     
{         
  // Give the subscriber a chance to process/modify the keystroke         
  var args = new KeyPressedEventArgs(stroke);
  OnKeyPressed(this, args);     
  stroke = args.Stroke;
} 

Дайте вашему подписчику копию, а затем скопируйте ее обратно в локальное значение, как только оно будет сделано.

В качестве альтернативы,Вы можете создать свой собственный класс, представляющий нажатие клавиши и передать его подписчику?

...