Simulare un wordwrap su listbox in C#

Alcune volte è necessario inserire in una listbox delle righe (negli items) che vanno oltre la larghezza della listbox stessa.

Il controllo in sè non ha le proprietà, ma neanche le responsabilità, per decidere come e quando tagliare le righe inserite.

Ovviamente questo è un esempio e va preso così com’è. Modificatelo poi per il vostro caso specifico.

– innanzitutto la proprietà DrawMode della listbox va posta a OwnerDrawFixed;
– quindi si deve definire un gestore per l’evento DrawItem della stessa listbox, come di seguito indicato :

private void ListBoxcheckuser_DrawItem(object sender, DrawItemEventArgs e)
{
ListBox myListbox = (ListBox)sender;
// disegna il background e definisco il brush
e.DrawBackground();
Brush myBrush = Brushes.Black;
// la stringa da mostrare nella riga
string sTextToDisplay =
myListbox.Items[e.Index].ToString();
// stabilisco la larghezza massima di ogni riga, in caratteri
int iLength = 50;
// se la lunghezza della stringa supera quella visibile, la taglio e
// faccio l'insert delle righe a seguire
if (sTextToDisplay.Length > iLength)
{
// ottengo il primo blocco (per la riga corrente)
string sFirstBlock = sTextToDisplay.Substring(0, iLength - 1);
// e quindi il secondo blocco (il rimanente della riga)
string sSecondBlock = sTextToDisplay.Remove(0, iLength - 1);
// assegno il primo blocco alla riga corrente (che ora
è stata modificata)
myListbox.Items[e.Index] = sFirstBlock; //
questa riga è fondamentale;
// inserisco la nuova riga all'indice successivo
// questo farà scattare nuovamente questo evento, per
la riga in questione
myListbox.Items.Insert(e.Index + 1, sSecondBlock);
// riporto il valore da stampare (disegnare)
sTextToDisplay = sFirstBlock;
}
// disegno il testo per la riga corrente (o quello che ne rimane)
e.Graphics.DrawString(sTextToDisplay, e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
// assegno il focus al rectangle se necessario
e.DrawFocusRectangle();
}

questo ti consente di determinare una lunghezza massima in caratteri del testo che viene inserito nella textbox;
l’unico svantaggio è che non è dinamico in base al font; a questo si può rimediare ragionando in termini di pixel, vedendo di volta in volta la larghezza della stringa da scrivere rispetto alla larghezza della listbox, tramite il metodo :

// ottengo il primo blocco (per la riga corrente)
int iPixel = TextRenderer.MeasureText(myString, myFont).Width;

ma è un’alternativa ancor più faticosa della prima, e poco gestibile (per il fatto che il DrawItem viene rilanciato ad ogni visualizzazione/refresh del controllo/della pagina)…

Pensavo che queste seghe mentali soluzioni geniali fossero solo un ricordo dell’epoca di Delphi

Simulare un wordwrap su listbox in C#

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...