Is there a free approach to handling WinForm events?

I was handling another KeyDown event in a user control when I wondered if there was a library in it to enter free code to handle an event like

editor.When(Keys.F).IsDown().With(Keys.Control).Do((sender, e) => ShowFindWindow()); 

Does it exist?

+6
c # winforms fluent
source share
3 answers

I decided it was a call, and it might let me know what Fluent is, so I coded the Fluent keyboard class. I don’t think that I follow all fluent language structures and rules, but it works.

Helper Extension Method

 /// <summary> /// Provides a set of static (Shared in Visual Basic) methods for starting a fluent expression on a <see cref="System.Windows.Form.Control"/> object. /// </summary> public static class ControlExtensions { /// <summary> /// Starts a fluent expression that occurs when a key is pressed. /// </summary> /// <param name="control">The control on which the fluent keyboard expression is occuring.</param> /// <param name="keys">The key when it will happen.</param> /// <returns>A <see cref="KeyboardFluent"/> object that makes it possible to write a fluent expression.</returns> public static KeyboardFluent When(this Control control, Keys keys) { return new KeyboardFluent(control).When(keys); } } 

Free class

 /// <summary> /// Represents a fluent expression for handling keyboard event. /// </summary> public class KeyboardFluent { /// <summary> /// The control on which the fluent keyboard expression is occuring. /// </summary> private Control control; /// <summary> /// The KeyDown and KeyUp handler. /// </summary> private KeyEventHandler keyHandler; /// <summary> /// Stores if the IsDown method was called and that the KeyDown event is registered. /// </summary> private bool isDownRegistered = false; /// <summary> /// Stores if the IsUp method was called and that the KeyUp event is registered. /// </summary> private bool isUpRegistered = false; /// <summary> /// The list of keys that will make the actions be executed when they are down or up. /// </summary> private List<Keys> triggerKeys; /// <summary> /// The modifiers keys that must be down at the same time than the trigger keys for the actions to be executed. /// </summary> private Keys modifiers; /// <summary> /// The list of actions that will be executed when the trigger keys and modifiers are down or up. /// </summary> private List<Action<object, KeyEventArgs>> actions; /// <summary> /// Initializes a new instance of the <see cref="KeyboardFluent"/> class. /// </summary> /// <param name="control">The control on which the fluent keyboard expression is occuring.</param> public KeyboardFluent(Control control) { this.control = control; this.triggerKeys = new List<Keys>(); this.actions = new List<Action<object, KeyEventArgs>>(); this.keyHandler = new KeyEventHandler(OnKeyHandler); } /// <summary> /// Handles the KeyDown or KeyUp event on the control. /// </summary> /// <param name="sender">The control on which the event is occuring.</param> /// <param name="e">A <see cref="KeyEventArgs"/> that gives information about the keyboard event.</param> private void OnKeyHandler(object sender, KeyEventArgs e) { if (this.triggerKeys.Contains(e.KeyCode) && e.Modifiers == this.modifiers) { this.actions.ForEach(action => action(sender, e)); } } /// <summary> /// Makes the keyboard event occured when a key is pressed down. /// </summary> /// <returns>Returns itself to allow a fluent expression structure.</returns> public KeyboardFluent IsDown() { if (!isDownRegistered) { this.control.KeyDown += this.keyHandler; isDownRegistered = true; } return this; } /// <summary> /// Makes the keyboard event occured when a key is pressed up. /// </summary> /// <returns>Returns itself to allow a fluent expression structure.</returns> public KeyboardFluent IsUp() { if (!isUpRegistered) { this.control.KeyUp += this.keyHandler; isUpRegistered = true; } return this; } /// <summary> /// Creates a new trigger on a key. /// </summary> /// <param name="key">The key on which the actions will occur.</param> /// <returns>Returns itself to allow a fluent expression structure.</returns> public KeyboardFluent When(Keys key) { this.triggerKeys.Add(key); return this; } /// <summary> /// Adds a modifier filter that is checked before the action are executed. /// </summary> /// <param name="modifiers">The modifier key.</param> /// <returns>Returns itself to allow a fluent expression structure.</returns> public KeyboardFluent With(Keys modifiers) { this.modifiers |= modifiers; return this; } /// <summary> /// Executes the action when the specified keys and modified are either pressed down or up. /// </summary> /// <param name="action">The action to be executed.</param> /// <returns>Returns itself to allow a fluent expression structure.</returns> public KeyboardFluent Do(Action<object, KeyEventArgs> action) { this.actions.Add(action); return this; } } 

Now i can enter

 public partial class Form1 : Form { public Form1() { InitializeComponent(); this.When(Keys.F).With(Keys.Control).IsDown().Do((sender, e) => MessageBox.Show(e.KeyData.ToString())); } } 

and it will display the message box only when Ctrl + F is not working.

+5
source share

I downloaded the Reactive Extension Framework for the .NET Framework 3.5 SP1.

I was able to do the same:

 Observable.FromEvent<KeyEventArgs>(this, "KeyDown") .Where(e => e.EventArgs.KeyCode == Keys.F && e.EventArgs.Modifiers == Keys.Control) .Subscribe(e => MessageBox.Show(e.EventArgs.KeyData.ToString())); 

This is quite powerful stuff.

+3
source share

.NET 4 will introduce a reactive framework ( IObservable<T> , IObserver<T> and helper extensions) that should offer just that.

+2
source share

All Articles