2008-09-15 9 views
7

Nella mia applicazione ho un controllo DataGridView che visualizza i dati per l'oggetto selezionato. Quando seleziono un oggetto diverso (in una casella combinata sopra), devo aggiornare la griglia. Sfortunatamente oggetti diversi hanno dati completamente diversi, anche colonne diverse, quindi ho bisogno di cancellare tutti i dati e le colonne esistenti, creare nuove colonne e aggiungere tutte le righe. Quando questo è fatto, l'intero controllo tremola in modo orribile e richiede anni. Esiste un modo generico per ottenere il controllo in uno stato di aggiornamento in modo che non ridisegni se stesso e quindi ridisegnarlo dopo aver completato tutti gli aggiornamenti?Sfarfallio durante gli aggiornamenti dei controlli in WinForms (ad esempio DataGridView)

E 'certamente possibile con TreeViews:

myTreeView.BeginUpdate(); 
try 
{ 
    //do the updates 
} 
finally 
{ 
    myTreeView.EndUpdate(); 
} 

C'è un modo generico per fare questo con altri controlli, DataGridView in particolare?

AGGIORNAMENTO: Siamo spiacenti, non sono sicuro di essere stato abbastanza chiaro. Vedo la "sfarfallio", perché dopo singola modifica il controllo viene ridisegnato sullo schermo, in modo da vedere la barra di scorrimento contrazione, ecc

+0

aggiungere questo in DataGridView DoubleBuffered (true); –

risposta

7

Invece di aggiungere le righe della griglia di dati uno alla volta, utilizzare il metodo DataGridView.Rows.AddRange per aggiungere tutti i file in una volta . Questo dovrebbe solo aggiornare il display una volta. C'è anche un DataGridView.Columns.AddRange per fare lo stesso per le colonne.

+0

Cheers, questo sembra il meglio che si possa ottenere con DataGridView – Grzenio

1

Sembra che si desidera doppio buffer:

http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

Sebbene sia utilizzato principalmente per i singoli controlli, è possibile implementarlo nel controllo Windows Form o in Modulo.

+2

Ho provato il doppio buffer, ma non è stato di grande aiuto. Penso che il problema è che cerca di ridisegnare dopo ogni riga che aggiungo, quindi finisce per aggiornare le prime file più volte. – Grzenio

1

Sfortunatamente, penso che questo potrebbe essere solo un sottoprodotto del framework .net. Sto vivendo uno sfarfallio simile anche se con controlli personalizzati. Molti dei materiali di riferimento che ho letto lo indicano, a parte il fatto che il metodo del doppio buffering non è riuscito a rimuovere lo sfarfallio.

6

Double buffering non aiuterà qui da quando che solo i buffer doppi dipingono le operazioni, il tremolio l'OP sta vedendo è il risultato di molteplici operazioni di verniciatura:

  • cancellare il contenuto di controllo -> riverniciare
  • Cancella colonne -> repaint
  • popolano nuove colonne -> repaint
  • aggiungere righe -> ridipingere

quindi questo è quattro ripetizioni per aggiornare il controllo, quindi lo sfarfallio. Sfortunatamente, non tutti i controlli standard hanno il BeginUpdate/EndUpdate che rimuove tutte le chiamate ripetitive fino a quando viene chiamato EndUpdate. Ecco cosa si può fare:

  1. avere un controllo diverso per ogni set di dati e mostrare/nascondere i controlli,
  2. Rimuovere il controllo dal suo genitore, l'aggiornamento e quindi aggiungere di nuovo il controllo,
  3. Scrivi la tua controllo proprio

Le opzioni 1 e 2 sfarfallerebbero ancora un po '.

Sul programma .Net GUI su cui sto lavorando, ho creato un set di controlli personalizzati che ha eliminato tutto lo sfarfallio.

+0

Sì, sono abbastanza sicuro che questo è esattamente il problema. E poiché devo aggiungere> 50 righe, puoi vedere come cresce la griglia. Quando hai creato i controlli, hai ampliato la visualizzazione griglia dati esistente o ne hai scritto uno nuovo da zero? – Grzenio

+0

Li ho scritti da zero, derivati ​​da UserControl e sono tutti molto specifici dell'applicazione. – Skizz

8

Il controllo .NET supporta i metodi SuspendLayout e ResumeLayout. Scegli il controllo genitore appropriato (ad es.il controllo che ospita i controlli che si desidera popolare) e fare qualcosa di simile al seguente:

this.SuspendLayout(); 

// Do something interesting. 

this.ResumeLayout(); 
+2

Sì, l'ho provato ma semplicemente non funziona :( – Grzenio

2

Questo ha funzionato per me.

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

Fondamentalmente, si tratta derivante dal controllo desiderato e impostando le seguenti stili.

SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true); 
7

persone sembrano dimenticare una semplice correzione per questo:

Object.Visible = false; 

//do update work 

Object.Visible = true; 

So che sembra strano, ma che funziona. Quando l'oggetto non è visibile, non si ridisegnerà. È comunque necessario eseguire l'aggiornamento begin e end.

+0

Questo dovrebbe avere molti più punti, mi avrebbe risparmiato un sacco di tempo. lavoro per il mio caso d'uso ma questo era perfetto. Grazie! –

0

Si può anche provare questo, il suo lavoro.

public static void DoubleBuffered(Control formControl, bool setting) 
{ 
    Type conType = formControl.GetType(); 
    PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); 
    pi.SetValue(formControl, setting, null); 
} 
Problemi correlati