If you need to listen to keys in any generic class what are pressed when a 'Form' Window, this is your code. It doesnt listen to global windows key events, so it cannot be used to see keys when the window is not active.
Form.cs
public partial class Form1 : Form
{
public Form1()
{
// Some other Code
// Register all Keys pressed
this.KeyPreview = true;
KeyHandler.Instance.Init();
this.KeyDown += Form1_KeyDown;
this.KeyUp += Form1_KeyUp;
// Some other Code in the constructor
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
// Fire event when a key is released
KeyHandler.Instance.FireKeyUp(sender, e);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
// Fire event when a key is pressed
KeyHandler.Instance.FireKeyDown(sender, e);
}
}
KeyHandler.cs
KeyHandler is a Singleton Class and can be accessed in any other Object through Handler.Instance... Easy right.
public class KeyHandler
{
#region Singleton
private static KeyHandler instance;
private KeyHandler()
{
currentlyPressedKeys = new List<Keys>();
}
public static KeyHandler Instance
{
get
{
if (instance is null)
{
instance = new KeyHandler();
}
return instance;
}
}
#endregion Singleton
private List<Keys> currentlyPressedKeys;
public List<Keys> GetCurrentlyPressedKeys { get { return currentlyPressedKeys; } }
public void FireKeyDown(object sender, KeyEventArgs e)
{
if (!currentlyPressedKeys.Contains(e.KeyCode))
{
currentlyPressedKeys.Add(e.KeyCode);
KeyEventKeyPressed(sender, e);
}
}
public void FireKeyUp(object sender, KeyEventArgs e)
{
currentlyPressedKeys.Remove(e.KeyCode);
KeyEventKeyReleased(sender, e);
}
public event EventHandler<KeyEventArgs> KeyPressed;
protected virtual void KeyEventKeyPressed(object sender, KeyEventArgs e)
{
EventHandler<KeyEventArgs> handler = KeyPressed;
handler?.Invoke(sender, e);
}
public event EventHandler<KeyEventArgs> KeyReleased;
protected virtual void KeyEventKeyReleased(object sender, KeyEventArgs e)
{
EventHandler<KeyEventArgs> handler = KeyReleased;
handler?.Invoke(sender, e);
}
public void Init()
{
// Nothing to initialize yet
}
}
// In any other Class/Object its now possible to receive KeyEvents that are fired when the 'Form' is active. So its possible to listen to key events in any Control object or anything else. Its possible to see if e.g. multiple keys are pressed like Shift+Ctrl+Q or something like that.
public class SomeClass
{
public SomeClass()
{
KeyHandler.instance.KeyPressed += Instance_KeyPressed
KeyHandler.Instance.KeyReleased += Instance_KeyReleased;
}
public void SomeMethod()
{
if (KeyHandler.Instance.GetCurrentlyPressedKeys.Contains(Keys.ShiftKey))
{
// Do Stuff when the method has a key (e.g. Shift/Control...) pressed
}
}
private void Instance_KeyPressed(object sender, KeyEventArgs e)
{
// Any Key was pressed, do Stuff then
}
private void Instance_KeyReleased(object sender, KeyEventArgs e)
{
// Do Stuff when a Key was Released
}
}