C# Creazione di un user control con .Net 7 estendere una textbox

Articolo che vuole introdurre il lettore alla creazione di controlli personalizzati.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

In questo articolo vedremo come estendere il controllo della casella di testo (textbox) aggiungendo particolarità funzionalità quale la possibilità di scrivere solo numeri, o solo lettere, ed altri interessanti personalizzazioni che possono tornare utili nello sviluppare applicazioni di tipo “Windows Application”.
L’articolo vuole fornire al lettore la conoscenza di base per la creazione di controlli personalizzati, detti usercontrol) che si possono riutilizzare in altri progetti e ed in altre applicazioni.
Gli userControl, permettono la creazione dei controlli personalizzati che possono estendere quelli già disponibili per lo sviluppo di applicazioni di tipo eseguibile, oltre ad offrire la possibilità di riutilizzarli in più progetti senza riscrivere il codice tante volte.
Nell’articolo vedremo come creare un controllo personalizzato con l’ultima versione del Framework .Net, al momento in cui si sta scrivendo l’articolo è il 7, con l’ambiente di sviluppo Visual Studio 2022 Community ed il linguaggio di programmazione C#.

Creazione del progetto


Si crea un nuovo progetto di tipo “App Windows forms” impostando un nome  e nella finestra successiva selezionare la versione del Framework  7.
Ultimata la creazione del progetto, aggiungiamo al progetto un nuovo elemento di tipo “Controllo Utente”, il tutto tramite il pulsante destro sul nome progetto nella finestra di “Esplora soluzioni”, e dal menu che viene visualizzato, selezionare la voce “Aggiungi” e nel sottomenu la voce “Controllo utente (Windows Forms)) il tutto come mostrato in figura 1.

Figura 1 – Il menu con la voce da selezionare

Figura 1 – Il menu con la voce da selezionare


A questo punto verrà creato quale nome impostare per il controllo (per esempio impostare UscTextBoxAvanzata) , assegnate un nome e confermate il tutto tramite il pulsante “OK”.
Nel controllo che sarà di colore griglio, trasciniamo un controllo di tipo “TextBox” con la proprietà “Name” impostata su “TxtTesto”, un controllo di tipo “Button” con la proprietà “Text” impostata con i tre pulsantini piccoli, la proprietà “Name” con il valore “btnFinestra” ed infine un controllo “Textbox” con la proprietà “Name” impostata su “TxtErrore”, la proprietà “MultiLine” su “True” e la proprietà “ReaOnly” impostata a true, il tutto come mostrato in figura 2.

Figura 2 – Il controllo personalizzato.

Figura 2 – Il controllo personalizzato.


Il pulsante avrà la funzionalità di aprire una finestra di selezoinare cartella e riportare nella casella di testo (TxtTesto) il percorso e nome del file che ha selezionato. Mentre la casella della parte inferiore, visualizzerà un messaggio di errore.


Stesura del codice


Terminata la creazione dell’aspetto grafico della casella personalizzata non resta che scrivere il codice.
Il codice che andremo a creare sarà quello di far comprendere come creare delle proprietà che permettono di personalizzare il controllo secondo le esigenze dell’utente, inoltre è anche un modo per capire come impostare alcune informazioni e visualizzare il tutto nella barra delle proprietà.
Facciamo doppio click sul pulsante, in modo che passiamo in visualizzazione codice nell’evento click del pulsante.
In questo evento, scriviamo il codice per visualizzare a video una finestra per dove salvare il file e riportare nella casella di testo, il percorso e nome del file.
Qui di seguito si riporta il frammento di codice delle suddette operazioni.

C#
private void btnFinestra_Click(object sender, EventArgs e)
       {
           OpenFileDialog openDlg = new OpenFileDialog();
           openDlg.Title = "Trova Percorso";
           if (openDlg.ShowDialog() == DialogResult.OK)
           {
               TxtTesto.Text = openDlg.FileName;
           }
       }

Terminata la stesura per la visualizzazione di una finestra modale per la selezione di un file, scriviamo il codice per creare delle proprietà, il quale programmatore imposterà per eseguire determinate funzioni.  Le proprietà che andremo a creare riguardano vari tipi, una di tipo booleana che ci permette di rendere il pulsante visibile o nascosto, un’altra di tipo enumerazione, con il quale imposteremo che la digitazione dei dati dev’essere solo numerica o solo testo.
Di seguito si riporta il frammento di codice per la creazione di una proprietà di tipo booleana che permette di rendere il pulsante visibile o nascosto, ed in base a determinati attributi fornire informazioni nella barra delle proprietà dell’ambiente di sviluppo, quale il tipo di valore ammesso, una descrizione, in quale categoria inserire la proprietà ed il valore di default.
Di seguito si riportano le suddette operazioni per la creazione della proprietà

C#
[Browsable(true)]
       [Description("Visualizza se il pulsante dev'essere visibile oppure no.")]
       [Category("Layout")]
       [DefaultValue(true)]
       public bool VisibilePulsante
       {
           get => btnFinestra.Visible;
           set => btnFinestra.Visible = value;
       }

Ora dobbiamo creare oggetto di tipo “enumerazione”, che utilizzeremo per gestire la proprietà e che permetterà di validare in dati in base al carattere digitato nella casella di testo.
Di seguito si riporta il codice per il tipo enum che utilizzeremo per la proprietà.

C#
public enum TipoDiCasella
       {
           Standard,
           Testo,
           Numerica
       }

Il frammento di codice precedente, crea un enum con tre voci, con il valore “standard” permette di digitare qualunque testo, con il valore “Testo” solo caratteri dalla A alla Z, con il valore “Numerica” solo numeri.
Per gestire la selezione del dato o rilevarlo, occorre creare una variabile di livello classe, che possiamo utilizzare sia per la proprietà e sia durante l’evento di digitazione della casella di testo.
Di seguito si riporta il frammento di codice della creazione della variabile membro.

C#
 private TipoDiCasella m_TipoCasella;

Questa variabile la utilizzeremo per impostare o rilevare il valore che il programmatore ha impostato nella finestra delle proprietà per indicare il tipo di casella da utilizzare.
La proprietà sarà del tipo dell’enumerazione creata in precedenza, con il valore di default impostato su “Standard”.
Di seguito si riporta il frammento di codice delle suddette operazioni.

C#
[Browsable(true)]
       [Description("Visualizza la tipologia della casella.")]
       [Category("Layout")]
       [DefaultValue(TipoDiCasella.Standard)]
       public TipoDiCasella TipoCasella
       {
           get => m_TipoCasella;
           set => m_TipoCasella = value;
       }

Come si è visto dal frammento di codice precedente, oltre ad impostare i vari attributi che saranno visibili nella finestra delle proprietà dell’ambiente di sviluppo “Visual Studio”, quali la descrizione, la categoria, il tipo di proprietà che è enumerazione che restituisce o imposta la variabile privata creata come membro della classe.
A questo punto è rimasta l’ultima modifica, quella di verificare nell’evento “keyPress” il carattere digitato e verificare se è valido o no in base alla proprietà “tipoCasella”.
Passiamo in visualizzazione grafica, e nella casella di testo facciamo doppio click nell’evento “KeyPress” della finestra delle proprietà, in questo modo viene visualizzata la parte di codice nell’evento.
In quest’evento, verifichiamo il valore impostato per la proprietà “TipoCasella” in questo modo viene gestito il carattere digitato e se validarlo oppure no.
Di seguito si riporta il frammento di codice dell’evento Keypress della casella di testo nel quale viene utilizzata la proprietà creata in precedenza

C#
private void TxtTesto_KeyPress(object sender, KeyPressEventArgs e)
       {
           TxtErrore.Text = "";
           if (m_TipoCasella == TipoDiCasella.Numerica)
           {
               if (char.IsNumber(e.KeyChar.ToString(), 0) == false)
               {
                   e.Handled = true;
                   TxtTesto.Select(0, TxtTesto.Text.Length);
                   TxtErrore.Text = "Solo numeri.";
                   TxtErrore.Visible = true;
               }
           }
           if (m_TipoCasella == TipoDiCasella.Testo)
           {
               if (char.IsLetter(e.KeyChar.ToString(), 0)==false)
               {
                   e.Handled = true;
                   TxtTesto.Select(0, TxtTesto.Text.Length);
                   TxtErrore.Text = "Solo lettere.";
                   TxtErrore.Visible = true;
               }
           }
       }

Come si è visto nel precedente frammento di codice, qualora la validazione del carattere non è convalidata, visualizza un messaggio di errore tramite la casella di testo denominata “TxtErrore”, fornendo così all’utente un messaggio informativo.
Di seguito si riporta il codice completo dell’articolo per fornire al lettore una visione completo di quanto illustrato e per poter avere una base su cui iniziare.

C#
public partial class UscTextBoxAvanzata : UserControl
   {
       public UscTextBoxAvanzata()
       {
           InitializeComponent();
       }
       public enum TipoDiCasella
       {
           Standard,
           Testo,
           Numerica
       }
       private TipoDiCasella m_TipoCasella;
       [Browsable(true)]
       [Description("Visualizza se il pulsante dev'essere visibile oppure no.")]
       [Category("Layout")]
       [DefaultValue(true)]
       public bool VisibilePulsante
       {
           get => btnFinestra.Visible;
           set => btnFinestra.Visible = value;
       }
       [Browsable(true)]
       [Description("Visualizza la tipologia della casella.")]
       [Category("Layout")]
       [DefaultValue(TipoDiCasella.Standard)]
       public TipoDiCasella TipoCasella
       {
           get => m_TipoCasella;
           set => m_TipoCasella = value;
       }
       private void btnFinestra_Click(object sender, EventArgs e)
       {
           OpenFileDialog openDlg = new OpenFileDialog();
           openDlg.Title = "Trova Percorso";
           if (openDlg.ShowDialog() == DialogResult.OK)
           {
               TxtTesto.Text = openDlg.FileName;
           }
       }
       private void TxtTesto_KeyPress(object sender, KeyPressEventArgs e)
       {
           TxtErrore.Text = "";
           if (m_TipoCasella == TipoDiCasella.Numerica)
           {
               if (char.IsNumber(e.KeyChar.ToString(), 0) == false)
               {
                   e.Handled = true;
                   TxtTesto.Select(0, TxtTesto.Text.Length);
                   TxtErrore.Text = "Solo numeri.";
                   TxtErrore.Visible = true;
               }
           }
           if (m_TipoCasella == TipoDiCasella.Testo)
           {
               if (char.IsLetter(e.KeyChar.ToString(), 0)==false)
               {
                   e.Handled = true;
                   TxtTesto.Select(0, TxtTesto.Text.Length);
                   TxtErrore.Text = "Solo lettere.";
                   TxtErrore.Visible = true;
               }
           }
       }
   }

Conclusioni


L’articolo ha fornito al lettore le basi per la creazione di controlli personalizzati in ambito di “Windows Application”, permettendo di vedere uno scenario molto ampio e che offre grande potenzialità ed opportunità di business, per migliorare lo sviluppo software.
La creazione dei controlli è una tecnica che in passato era molto utilizzata anche per dotare quelle funzionalità ed aspetti grafici ai controlli standard che non erano presenti.