Instead of implementing this in a timer, why not use another thread, and continuously check the state of the control, firing an event on the form when a button is pressed and when it is released.
Form Code:
public partial class FormWithExternalEvents : Form
{
private GamepadEvents gpe;
public FormWithExternalEvents()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
gpe = new GamepadEvents();
gpe.JoystickButtonDown += b =>
{
if (this.InvokeRequired) this.Invoke((GamepadButtonEvent) gpe_JoystickButtonDown);
else gpe_JoystickButtonDown(b);
};
gpe.JoystickButtonUp += b =>
{
if (this.InvokeRequired) this.Invoke((GamepadButtonEvent)gpe_JoystickButtonUp);
else gpe_JoystickButtonUp(b);
};
var thread = new Thread(gpe.Run);
thread.Start();
base.OnLoad(e);
}
void gpe_JoystickButtonUp(SharpDX.XInput.GamepadButtonFlags button)
{
throw new NotImplementedException();
}
void gpe_JoystickButtonDown(SharpDX.XInput.GamepadButtonFlags button)
{
throw new NotImplementedException();
}
}
Code of the class that will be running on another thread:
public delegate void GamepadButtonEvent(GamepadButtonFlags button);
public class GamepadEvents
{
public event GamepadButtonEvent JoystickButtonUp;
public event GamepadButtonEvent JoystickButtonDown;
private bool[] buttonsBools = new bool[32];
public void Run()
{
while (true)
{
var controller = new Controller();
State s = controller.GetState();
ButtonSignal(0, GamepadButtonFlags.DPadUp, (s.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0);
ButtonSignal(1, GamepadButtonFlags.DPadDown, (s.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0);
ButtonSignal(2, GamepadButtonFlags.DPadLeft, (s.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0);
ButtonSignal(3, GamepadButtonFlags.DPadRight, (s.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0);
ButtonSignal(4, GamepadButtonFlags.Start, (s.Gamepad.Buttons & GamepadButtonFlags.Start) != 0);
ButtonSignal(5, GamepadButtonFlags.Back, (s.Gamepad.Buttons & GamepadButtonFlags.Back) != 0);
ButtonSignal(6, GamepadButtonFlags.LeftThumb, (s.Gamepad.Buttons & GamepadButtonFlags.LeftThumb) != 0);
ButtonSignal(7, GamepadButtonFlags.RightThumb, (s.Gamepad.Buttons & GamepadButtonFlags.RightThumb) != 0);
ButtonSignal(8, GamepadButtonFlags.LeftShoulder, (s.Gamepad.Buttons & GamepadButtonFlags.LeftShoulder) != 0);
ButtonSignal(9, GamepadButtonFlags.RightShoulder, (s.Gamepad.Buttons & GamepadButtonFlags.RightShoulder) != 0);
ButtonSignal(10, GamepadButtonFlags.A, (s.Gamepad.Buttons & GamepadButtonFlags.A) != 0);
ButtonSignal(11, GamepadButtonFlags.B, (s.Gamepad.Buttons & GamepadButtonFlags.B) != 0);
ButtonSignal(12, GamepadButtonFlags.X, (s.Gamepad.Buttons & GamepadButtonFlags.X) != 0);
ButtonSignal(13, GamepadButtonFlags.Y, (s.Gamepad.Buttons & GamepadButtonFlags.Y) != 0);
Thread.Sleep(1);
}
}
private void ButtonSignal(int btnIdx, GamepadButtonFlags gamepadButton, bool pressed)
{
bool wasPressed = buttonsBools[btnIdx];
buttonsBools[btnIdx] = pressed;
if (wasPressed && !pressed)
this.JoystickButtonUp(gamepadButton);
if (!wasPressed && pressed)
this.JoystickButtonDown(gamepadButton);
}
}