Domanda

Questa è un'applicazione Desktop C #.La proprietà DrawStyle del mio ListBox è impostata su OwnerDrawFixed.

Il problema: Sostituisco il DrawItem per disegnare il testo in caratteri diversi e funziona.Ma quando inizio a ridimensionare il modulo in runtime, l'elemento selezionato viene disegnato correttamente, ma il resto di loro non è ridisegnato, causando il testo che sembrava corrotto per gli articoli non selezionati.

Ecco il mio codice:

private void listDevices_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();

    string textDevice = ((ListBox)sender).Items[e.Index].ToString();

    e.Graphics.DrawString(textDevice,
        new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black), 
        e.Bounds, StringFormat.GenericDefault);


    // Figure out where to draw IP
    StringFormat copy = new StringFormat(
        StringFormatFlags.NoWrap |
        StringFormatFlags.MeasureTrailingSpaces
    );
    copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)});

    Region[] regions = e.Graphics.MeasureCharacterRanges(
        textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy);

    int width = (int)(regions[0].GetBounds(e.Graphics).Width);
    Rectangle rect = e.Bounds;
    rect.X += width;
    rect.Width -= width;

    // draw IP
    e.Graphics.DrawString(" 255.255.255.255",
        new Font("Courier New", 10), new SolidBrush(Color.DarkBlue),
        rect, copy);

    e.DrawFocusRectangle();
}

listDevices.Items.Add("Device001");
listDevices.Items.Add("Device002");
.

Inoltre, l'oggetto che viene disegnato correttamente (quello selezionato) è tremolante sul ridimensionamento del modulo.No Biggie, ma se qualcuno sa perché .... TNX

È stato utile?

Soluzione

Metti il seguente codice nell'evento Ridimensione:

private void listDevices_Resize(object sender, EventArgs e) {
    listDevices.Invalidate();
}
.

Questo dovrebbe far sì che tutto sia ridisegnato.

Per fermare lo sfarfallio, è necessario un doppio buffering.

Per fare ciò, creare una nuova classe, derivata da elenco e inserire quanto segue nel costruttore:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
.

O semplicemente incollarlo in un file di codice:

using System.Windows.Forms;

namespace Whatever {
    public class DBListBox : ListBox {
        public DBListBox(): base() {
            this.DoubleBuffered = true;
            // OR
            // this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
    }
}
.

Sostituisci "Qualunque cosa" con lo spazio dei nomi usa il tuo progetto, o renderlo qualcosa di più utile.Dopo aver compilato, dovresti essere in grado di aggiungere un Dblisbox nel progettista del modulo.

Altri suggerimenti

I repro il problema. Ci sono diversi errori nel codice, il nome del carattere è "Arial", non è necessario regolare RET.width, si dimentica di chiamare smaltire () sui font, i pennelli e le regioni. Ma non spiegano il comportamento. C'è qualcosa di sbagliato nell'area di clipping che impedisce il testo di essere aggiornato correttamente. Non vedo dove si verifica, lo stato dell'oggetto grafico è a posto.

graphics.drawstring () è un metodo molto turbato, dovresti davvero evitarlo. Tutti i controlli di Windows Forms, inclusa la casella di riepilogo, utilizzare TEXTRENDERER.DRAWTEXT (). Che risolve il problema quando lo uso. So che la misurazione è più difficile, potresti lavorare attorno a quello visualizzando l'indirizzo IP su un offset fisso. Sembra che anche meglio, si allineeranno in una colonna in questo modo.

Scallezzalo perché usi e.drawbackground (). Ciò cancella il testo esistente, disegni il testo su di esso. Non penso che il doppio buffering lo risolverà, dovrai disegnare l'intero oggetto in modo da non dover disegnare lo sfondo. Tricky Se non riesci a ottenere le dimensioni esatte del testo con il carattere grande, una soluzione alternativa è quella di disegnare prima in una bitmap.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top