Molto spesso può succedere di avere dei comportamenti comuni a più Forms, che se gestiti manualmente genererebbero codice ripetitivo e quindi problemi in caso di successivi cambiamenti e manutenzione delle form, in questi casi, è possibile usare un metodo statico per assegnare ai controlli interessati un eventhandler che aggiunga la funzionalità richiesta.
Per fare un esempio, ho generato un progetto Windows Forms, in cui ho inserito tre form, chiamati rispettivamente FrmMain, FrmOne, FrmDue, ed una classe statica EventHelper.
FrmMain è una form MDI con una MenuStrip in cui ho inserito due opzioni, per richiamare le due form secondarie, in ognuna di esse ho inserito vari tipi di controlli.
Lo scopo della mia funzione, è fare in modo che il tasto Enter funzioni come il tabulatore, facendo passare il focus da un controllo all'altro. In questo caso è una funzione applicabile a tutti i tipi di controllo.
private void generaUnChildDiTipoUnoToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
FrmChildOne frmOne = new FrmChildOne();
frmOne.MdiParent = this;
frmOne.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void generaUnChildDiTipoDueToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
FrmChildDue frmDue = new FrmChildDue();
frmDue.MdiParent = this;
frmDue.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I metodi della FrmMain per la chiamata delle form
private void FrmChildOne_Load(object sender, EventArgs e)
{
EventHelper.SetEnterLikeTabAllControls(this);
} private void FrmChildDue_Load(object sender, EventArgs e)
{
EventHelper.SetEnterLikeTabAllControls(this);
}
Gli EventHandler delle due form figlie che chiamano la nostra funzione per l'assegnazione dell'eventhandler a tutti i controlli della form.
Ed ora le funzioni per aggiungere la nostra funzionalità alle form.
private static void KeyDownEnterControl(object sender, KeyEventArgs e)
{
try
{
TextBox txt = sender as TextBox;
if (txt == null || txt.Multiline == false)
{
if (e.KeyCode == Keys.Enter && !e.Shift && !e.Control && !e.Alt)
{
e.Handled = true;
SendKeys.Send("\t");
}
}
}
catch (Exception ex)
{
throw new ApplicationException(" " + mClassName + "."
+ System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
}
}
Ecco l'event handler generico, che sostituisce il tasto con un tasto a tutti i controlli salvo le Textbox multiline.
public static KeyEventHandler KeyDownEnter()
{
try
{
return new System.Windows.Forms.KeyEventHandler(KeyDownEnterControl);
}
catch (Exception ex)
{
throw new ApplicationException(" " + mClassName + "."
+ System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
}
}
E la funzione che genera il Delegate all'evento da assegnare ai controlli.
public static void SetEnterLikeTabAllControls(Control pControl)
{
try
{
foreach (Control ctr in pControl.Controls)
{
if (ctr.Controls.Count > 0)
{
SetEnterLikeTabAllControls(ctr);
}
else
{
Control uba = ctr as Control;
if (uba != null)
{
uba.KeyDown += KeyDownEnter();
}
}
}
}
catch (Exception ex)
{
throw new ApplicationException(" " + mClassName + "."
+ System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
}
}
Ed infine, la funzione ricorsiva che cicla su tutti i controlli che non sono contenitori, assegnando all'event handler KeyDown la nostra funzione.
Il link per scaricare il progetto su cui ho fatto l'esperimento è qui.
Come sempre, domande, correzioni, osservazioni sono bene accette.
Tags: eventhandler, static, classi