ListView zeigt Columns nach Begin - End Update nicht mehr
-
Hallo Community,
C++
Borland C++ 2007
Ich habe folgendes Problem, ich nutze in meinem Programm in meheren
Formularen Listviews.
Im Konstruktor lege ich in den Listviews meist mehrere Spalten anTListColumn *NewColumn; ListView2->ViewStyle = vsReport; ListView2->ReadOnly = true; ListView2->Color = clWindow; ListView2->Font->Color = clWindowText; ListView2->RowSelect = true; ListView2->ReadOnly = true; ListView2->MultiSelect = false; ListView2->GridLines = true; ListView2->HideSelection = false; NewColumn = ListView2->Columns->Add(); NewColumn->Alignment = taLeftJustify; NewColumn->Caption = "Name"; NewColumn->Width = 150; ...
In dem Programm wird dann eine Funktion mehrmal aufgerufen die das ListView füllt, um das ständige Flackern abzustellen udn die ListView zu beschleunigen
verwende ich Begin und EndUpdate.
Vorher: FLacker und Langsam aber alles wird dargestellt.
Jetzt : Schneller und Kein Flackern, aber bei einigen Listviews werden die Spaltenköpfe komplett Grau gezeigt und erst beim daraufclicken erscheint der Name
oder bei einem zweiten öffnen des Formulars.void __fastcall TFormStoerstatDef::ListView2Fuellen() { ListView2->Items->BeginUpdate(); //Si035 - Test ! int count = ListView2->Items->Count; // nicht direkt verwenden, da lfd. aktualisiert wird for (int i=0; i < count; i++) ListView2->Items->Delete(0); TListItem *ListItem; SqlSocket->SQL->Clear(); SqlSocket->SQL->Add(Filter); SqlSocket->Open(); if (SqlSocket->SqlTab->Records->Count) { SqlSocket->First(); for (int i=0; i < SqlSocket->SqlTab->Records->Count; i++) { ListItem = ListView2->Items->Add(); ListItem->Caption = SqlSocket->SqlTab->FieldByName("Name"); ListItem->SubItems->Add(SqlSocket->SqlTab->FieldByName("Linie")); ... SqlSocket->Next(); } } SqlSocket->Close(); ListView2->Items->EndUpdate(); }
Frage ist nun wie kann ich das verhindern?!
Habe schon probiert nach dem BeginUpdate die Columns erneut anzulegen , doch dies funktioniert auch nicht "immer".Noch Andere Vorschläge, Ideen??!
Danke
Mfg
aLx
-
Ich sehe du hast das BeginUpdate auf die Items gesetzt.
Setze es doch auf die Columns! Also z.B. Columns->BeginUpdate oder so ähnlich...
-
Bist du sicher, dass zu jedem BeginUpdate() auch der entsprechende EndUpdate() Aufruf durchgeführt wird? Oder kann es sein, dass das Durchlaufen der Datensätze sehr lange dauert und der EndUpdate() Aufruf noch nicht stattgefunden hat?
Ich habe mir für diesen Fall ein Guard Objekt gebaut, das sicherstellt, dass die Begin- und EndUpdate() Aufrufe immer paarweise durchgeführt werden:struct ListViewUpdateGuard { TListView& LV ListViewUpdateGuard( TListView& op ) : LV( op ) { LV.Items->BeginUpdate(); } ~ListViewUpdateGuard() { LV.Items->EndUpdate(); } };
Im Gebrauch sieht´s dann so aus:
void TForm::show_items() { if( NULL == MyListView ) return; // Aktualisierung des ListView bis zum Verlassen der Methode aussetzen ListViewUpdateGuard( *MyListView ); for( unsigned int Index = 0; Index < Count; ++Index ) { TListItem* Item = MyListView->Items->Add(); ... } }
-
DocShoe schrieb:
Ich habe mir für diesen Fall ein Guard Objekt gebaut, das sicherstellt, dass die Begin- und EndUpdate() Aufrufe immer paarweise durchgeführt werden:[...]
In diesem Fall tut es doch auch ein try/__finally. Und wem das nicht paßt, der kann die Angelegenheit in C++Builder 2009 aufwärts etwas generischer lösen, so daß es nicht nötig ist, für jede Kleinigkeit eine eigene Guard-Struktur zu definieren:
#define UCL_PP_EXPAND(...) __VA_ARGS__ #define UCL_PP_CAT2_(a,...) UCL_PP_EXPAND(a ## __VA_ARGS__) #define UCL_PP_CAT2(a,...) UCL_PP_CAT2_(a, __VA_ARGS__) #define UCL_SAFEGUARD(arg, init, exit) \ class UCL_PP_CAT2(_SG_, __LINE__) \ { \ typedef decltype (arg) ArgType; /* should be a pointer type */ \ ArgType object; \ public: \ UCL_PP_CAT2(_SG_, __LINE__) (ArgType _object) : object (_object) { init; } \ ~UCL_PP_CAT2(_SG_, __LINE__) (void) { exit; } \ } UCL_PP_CAT2(_vSG_, __LINE__) (arg)
Benutzung so:
void __fastcall TFormStoerstatDef::ListView2Fuellen() { UCL_SAFEGUARD (ListView2->Items, object->BeginUpdate (), object->EndUpdate ()); ... }
-
Also es gibt zu jedem BeginUpdate auch ein EndUpdate.
Das komische ist das es nur in manchen Formularen auftritt, und dies aber auf jedem Rechner wieder anders ist.Bei den Formularen wo es auftritt sind meist nicht viele Datensätze in den ListViews, und dennoch erscheinen die Columns nicht.
Bei denen die viele Sätze beinhalten und es lang dauert, geschiet dies nicht.
Kann auch zufall sein. Aber Funktionsweiße ist in allen Formularen gleich.
Anlegen wie beschrieben
und anschließend mehrmaliges Füllen.
Beim 1. Aufruf sind bei manchen die Spaltenüberschriften ausgegraut, also komplett grau ohne Schrift und Text.ich probiere mach zusätzlich das begin und EndUpdate für die Columns...
Danke
-
Also das Sperren der Columns hat keinerlei Auswirkungen auf die fehlerhafte Darstellung, habe auch schon umgestellt, ebenfalls keine Auswirkungen.
Die Sache mit try und __Finally hat auch keinen Erfolg gezeigt.
Hab nun das Begin und Endupdate aus den Routinen wieder entfernt.
Bis auf ein Formular
werden nun wieder alle korrekt dargestellt.Hat jemand noch andere Vorschläge?!
Bestimmte Reihenfolge einhalten?!Begin und EndUpdate direkt in der Schleife?!
DAnke