A couple of examples:
- A simple shared class that allows to subscribe to events using predefined event handlers.
- A Custom Control that can filter key presses based on specific allowed patterns. Here, I'm using what you posted earlier in relation to the
KeyPress
event filters. This filter may need some more attention.
I've added, as an example, a public Property, public bool NumbersOnly
, which can be used to make the custom TextBox control accept only numbers. It purges the text from any non digits chars when it's activated. An ErrorProvider
gives feedback when a key that is not allowed is pressed.
Sample centralized Event Handler.
public partial class SomeForm : Form
{
public SomeForm()
{
InitializeComponent();
// Get all TextBoxes in the current Form and subscribe to some events
foreach (var textBox in this.FindAll<TextBox>()) {
textBox.TextChanged += MyEventsHandler.TextBoxTextChanged_Handler;
textBox.KeyPress += MyEventsHandler.TextBoxKeyPress_Handler;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
foreach (var textBox in this.FindAll<TextBox>()) {
textBox.TextChanged -= MyEventsHandler.TextBoxTextChanged_Handler;
textBox.KeyPress -= MyEventsHandler.TextBoxKeyPress_Handler;
}
base.OnFormClosing(e);
}
}
Simple events handler class:
internal static class MyEventsHandler
{
internal static void TextBoxTextChanged_Handler(object sender, EventArgs e)
{
var txt = sender as TextBox;
Console.WriteLine(txt.Text);
}
internal static void TextBoxKeyPress_Handler(object sender, KeyPressEventArgs e)
{
if (Regex.Match(e.KeyChar.ToString(), @"[^a-zA-Z0-9\s]").Success) {
e.Handled = true;
}
}
}
Extension method:
public static class ControlExtensions
{
public static IEnumerable<T> FindAll<T>(this Control control) where T: Control
{
foreach (Control ctl in control.Controls) {
foreach (Control child in ctl.FindAll<T>()) {
if (child is T ch) yield return ch;
}
if (ctl is T c) yield return c;
}
}
}
Specialized Custom Control, inheriting TextBox
IMO, it's better to have all the filtering logic in one single Control that can be further expanded when needed
using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Windows.Forms;
[ToolboxItem(true)]
[DesignerCategory("Code")]
public class TextBoxEx : TextBox
{
private const int ES_NUMBER = 0x2000;
private bool m_NumbersOnly = false;
private Regex regex = new Regex(@"[^a-zA-Z0-9\s\b]", RegexOptions.Compiled);
public TextBoxEx() { }
public bool NumbersOnly {
get => m_NumbersOnly;
set {
if (m_NumbersOnly != value) {
m_NumbersOnly = value;
this.Text = Regex.Replace(this.Text, @"\D", "");
this.RecreateHandle();
}
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (regex.IsMatch(e.KeyChar.ToString())) {
e.Handled = true;
}
base.OnKeyPress(e);
}
protected override CreateParams CreateParams
{
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
get {
CreateParams cp = base.CreateParams;
if (m_NumbersOnly) {
cp.Style |= ES_NUMBER;
}
else {
cp.Style &= ~ES_NUMBER;
}
return cp;
}
}
}