2009-08-26 18 views
18

Ci sono molti articoli che affrontano lo sfarfallio in Windows Form. La maggioranza consiglia di impostare DoubleBuffered = true o impostare un gruppo di flag ControlStyle. Tuttavia, nessuno di questi aiuta a ridurre lo sfarfallio del TextBox.Come impedire a un controllo TextBox di Windows Form di sfarfallio durante il ridimensionamento?

Qui ci sono un paio di questioni connesse:

Per riprodurre il problema, creare un nuovo progetto WinForms, aggiungere un TextBox, consentono a più linee, disattivare avvolgere le parole, aggiungere un po 'di testo, impostare Anchor a sinistra + destra + alto + basso. Ora esegui e ridimensiona. Il testo sfarfalla. Per le caselle di testo all'interno di un paio di TableLayoutPanel nidificate, lo sfarfallio sul ridimensionamento è ancora peggiore.

Applicare le soluzioni proposte nelle domande di cui sopra al meglio non correggere lo sfarfallio; se ottengo sperimentale e impostato il protetto su TextBox posso romperlo completamente (abilitando UserPaint) ma non eliminare lo sfarfallio.

Quindi, esiste un modo per correggere lo sfarfallio del testo in un controllo TextBox?

+1

Post interessante, ho problemi simili con un controllo etichetta, ma sulla base del fatto che leggo DoubleBuffer deve essere impostato solo con AllPaintInWmPaint che dovrebbe essere impostato solo con UserPaint I non ha doppio buffer di esso ... – Ian

+0

@romkyns, ho aggiornato i miei ans con una soluzione che ho usato in passato. – Ash

risposta

15

io di solito uso un RichTextBox invece di una TextBox multilinea. Impostando le proprietà DetectUrls- e ShortcutsEnabled su false l'RTB si comporta in modo molto simile a un TextBox e ... è senza sfarfallio.

+0

Questa è sicuramente la soluzione più rapida e semplice. Ho preso un controllo personalizzato basato su TextBox e ho appena cambiato il genitore in RichTextBox e - problema risolto. – Andy

+0

Come non era questa la risposta accettata? È completamente preciso, grazie! (Certo, non aiuterebbe i problemi di sfarfallio per i controlli figlio che non erano caselle di testo, ma non era questa la domanda.) – neminem

0

Abbiamo riscontrato lo stesso tipo di problema in passato e risulta essere l'uso di pannelli di ancoraggio eccessivo e di layout tabella. Suggerirò, se possibile, di provare a ricostruire l'interfaccia utente con il minimo utilizzo dell'aggancio (poiché il pannello di layout della tabella utilizza anche l'ancoraggio interno).

+0

Ho anche osservato che lo sfarfallio peggiora quando aumenta il numero di controlli relativi al layout. Sfortunatamente c'è ancora uno sfarfallio anche con il layout minimo necessario per ottenere il ridimensionamento di base, come nel mio esempio. –

4

In Windows Form la proprietà DoubleBuffered non ha alcun effetto sui controlli secondari come le caselle di testo. Invece influenza solo il modulo o il pannello per cui è impostato.

Se si desidera il doppio buffering per elementi figlio in un modulo, è necessario implementare il doppio buffering manuale.

Bob Powell ha scritto uno good article (e altri) su come farlo.

Inoltre, da un forum answer Bob dice anche:

La proprietà di una finestra significa che essi sfarfallio incontrollabile perché non è possibile fare doppio-buffer al di fuori dell'area di destinazione di Windows. Un pannello con controlli figlio non può essere impostato su doppio buffer e ad esempio bambini.

L'unico modo per farlo correttamente è per creare un unico comando che fa tutto il disegno utilizzando una forma di sistema grafico modalità trattenuta.

Pertanto, per ottenere il ridimensionamento della casella di testo senza sfarfallio utilizzando il doppio buffering manuale è necessario eseguire in qualche modo il rendering della casella di testo sul buffer posteriore e quindi visualizzarlo come parte dell'aggiornamento memorizzato. Se possibile, non mi aspetto che sarebbe facile.

[Update]

Alcune altre risposte hanno detto che questo è un problema con Windows Form in particolare. Questo non è corretto, in realtà è più profondo di quello ed è causato da GDI di Windows. Ad esempio, apri Blocco note/Wordpad ecc. E incolla una grande porzione di testo, ridimensiona la finestra e noti lo stesso problema di sfarfallio.

Ecco una soluzione di base che ho usato anni fa per fare qualcosa di simile. Si tratta di un semplice modulo contenente una casella di testo multilinea e una classe personalizzata ereditata da Panel. Entrambi i controlli hanno la stessa posizione e dimensioni. Usa Forms ResizeBegin e ResizeEnd per mostrare il pannello durante il ridimensionamento e altrimenti la casella di testo. Non è perfetto ma elimina lo sfarfallio.

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     Bitmap bm = null; 

     private void textBox1_Resize(object sender, EventArgs e) 
     { 

      Graphics g = textBox1.CreateGraphics(); 

      if (g.VisibleClipBounds.IsEmpty == false) 
      { 
       bm = new Bitmap((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height); 

       textBox1.DrawToBitmap(bm, new Rectangle(0, 0, (int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height)); 

      } 

      g.Dispose(); 


     } 

     private void panelDB1_Paint(object sender, PaintEventArgs e) 
     { 
      if (bm != null) 
      { 
       e.Graphics.DrawImageUnscaled(bm, 0, 0,bm.Width,bm.Height); 
      } 
     } 

     private void Form1_ResizeBegin(object sender, EventArgs e) 
     { 
      panelDB1.BringToFront(); 
     } 

     private void Form1_ResizeEnd(object sender, EventArgs e) 
     { 
      panelDB1.SendToBack(); 
     } 
} 

class PanelDB : Panel 
{ 
    public PanelDB() 
    { 
     this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer,true);  
     //this.DoubleBuffered = true; 

    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
    } 
} 
+0

Grazie. L'articolo potrebbe essere utile a persone che non hanno familiarità con le tecniche del doppio buffering, ma in realtà non aiuta a rispondere alla domanda. Per quanto riguarda la proprietà delle finestre, ho la sensazione che il TextBox nativo di Windows sia intrinsecamente sfarfallio e questo è irrisolvibile senza hack estremi ... –

+0

Ho aggiunto un aggiornamento alla mia domanda. Sfortunatamente la risposta alla tua domanda è semplicemente "non puoi", comunque ho pensato che alcune informazioni di sfondo sarebbero state utili. – Ash

+0

Controllando parte del mio vecchio codice vedo che è semplice eseguire il rendering di una casella di testo senza sfarfallio, usando il metodo DrawToBitmap() su una bitmap di memoria. Ma ciò creerebbe semplicemente un'immagine sullo schermo della tua casella di testo che non sfarfalla mai quando ridimensionata, ma è completamente inutile in quanto non ti permette di inserire del testo. – Ash

-2

FUNZIONE LockWindow LUNGO CONTROLLO COME INVIARE ghDlg,% TEXT_UPPER,% WM_SETREDRAW, 0,0 CLEARBuffers End Function

FUNZIONE UnlockWindow AS LONG ClearBuffers controllo Invia ghDlg,% TEXT_UPPER,% WM_SETREDRAW, 1, 0 END FUNCTION

Problemi correlati