CListCtrl

kerian

Erfahrenes Mitglied
Ich habe da ein kleines Problem mit der Auswahl!
Das Auswählen aus der Liste funktioniert super.
Wenn ich aber jetzt einen Button auf meinem Tab
Dialog drücke, wird die zuvorausgewählte Zeile im
Ctrl leicht grau angezeigt. Wenn ich jetzt mit der Maus
draufgehe kann ich diese nicht anwählen. Ich muss erst
eine andere Zeile auswählen. Die vorige Zeile erscheint wieder
normal und ich kann diese jetzt anwählen. Meine Frage, wie kann ich
das aufheben und warun erscheit die Zeile grau?

Oh eine Sache habe ich noch.
Ich lese aus einer Datenbank die Werte aus und stelle sie in
meinem CListCtrl dar. Ich erzeuge zwei weiter Spalten in meine Liste,
wo ich den Code und Index speicher. Mit denen ich den Datensatz in meiner Datenbank wiederfinden kann. Der User soll aber die Spalten in der Liste nich sehen. Ich habe schon zimlich alles ausprubiert an Einstellungen!
 
Zuletzt bearbeitet:
Meine Frage, wie kann ich
das aufheben und warun erscheit die Zeile grau?
Die Zeile erscheint grau, weil ein anderes Control den Fokus hat. Warum die Liste ihn nicht korrekt beim Anklicken wiederbekommt, weiss ich auch nicht. Funktioniert sie denn, auch wenn die Zeile dann grau ist? Dann ist es nur ein Darstellungsproblem.

Zum zweiten Punkt: Die Tabelle bzw. Liste ist ein Stück Userinterface. Es ist keine gute Idee, da Implementationsdetails wie deine ID-Verwaltung reinzubasteln. CListCtrl bietet für jede Zeile ein "Userdata", in das du einen Pointer auf eine von dir erzeugte struct oder class schreiben kannst, um die Werte aufzunehmen. Auf die Weise musst du nicht mit den Spalten rumpfuschen.
 
Ja, die Liste funktioniert. Aber ich muss erste ein andere Zeile anklicken, dann verschwindet das graue.
Das mit Userdate muss ich erst nachlesen. Also soll ich zuerst die Daten in ein Array schreiben und dann nur die benötibten Daten zeigen!
 
Userdata ist 4 Byte gross. Du kannst es auch direkt verwenden für eine ID oder so, wenn dir 32 Bit reichen. Wenn nicht, mach dir sowas wie
Code:
 struct itemdata
{
  int code;
  int index;
};
Dann kanst du immer beim Erzeugen einer neuen Zeile ein neues Itemdata machen, und den Pointer darauf in das Itemdata schreiben (Mit SetItemData(), glaube ich).
Code:
 itemdata* pItemdata = new itemdata;
itemdata->code = 4711;
itemdata->index = 666;
MeinListcontrol.SetItemData( iMeineNeueZeile, pItemdata ); // <- unsicher
Über GetItemData() kommst du immer wieder an die Daten ran.
Du darfst nur nicht vergessen, die DInger am Ende und beim Löschen einer Zeilen vorher zu deleten.
 
Also das mit den Focus geht nur bedingt.
Ich habe mehrere CListCtrl nebeneinander. Wenn ich dann die CListCtrl
wechsle (oder auch woanders gehe) wird die zuvorausgewählte Zeile grau.
Wenn ich sie jetzt auswähle bekomme ich kei Focus auf die Zeile. Ich muss
zuerst eine andere Zeile auswählen und dann geht das. :confused:
 
Du darfst nur nicht vergessen, die DInger am Ende und beim Löschen einer Zeilen vorher zu deleten.
Dazu könnte man aber auch die Methode zum Zeilenlöschen überschreiben und in dieser Methode dann das Löschen der Datenstruktur von UserData vornehmen.
Das nur mal so als Anmerkung.

Gruß Homer
 
@Daniel:
Im Prinzip hast du recht. Es ist eine gute Idee, sowas zu verpacken.
Es bringt aber in diesem Fall auch eine Menge Problem mit sich, die Kerians Fähigkeiten im Moment eventuell übersteigen. (Sorrry, nicht böse gemeint)

Das verlagert (von Kerians Position gesehen) das Sich-ums-Löschen-Kümmern an eine andere Stelle. Ein eventueller User der Kontrollklasse, der sich nicht um die Implementierung kümmern muss (ebenso vielleicht ein Kerian mit einem gewissen Abstand zur eigenen Arbeit), hätte tatsächlich einen Vorteil dadurch, würde aber möglicherweise durch Probleme durch die Nichtvirtualität der beteiligten Mehoden zunichtegemacht.
Das delete müsste vermutlich nicht nur in DeleteItem() eingebaut werden, sondern auch in DeleteAllItems(), ausser wir können davon ausgehen, dass DeleteAllItems() DeleteItem() aufruft.
Dann wäre das noch das Problem, dass beide Methoden nicht virtuell sind - das kann zu Problemen führen, und zwar dann, wenn über das Interface der Basisklasse auf eine Instanz des Controls zugegriffen werden soll. In dem Fall kämen nicht die überschriebenen, sondern die Basisklassenversionen der Löschmethden zum Einsatz, was zu Lecks führen müsste. Vielleicht sehe ich das aber auch zu kritisch.
Ich würde die Löschmethoden nicht überschreiben, sondern eigens benannte Mehoden zur Löschung einführen.

Hoffentlich war das jetzt nicht zu konfus geschrieben - habe noch keinen Kaffee gehabt. ;)
 
Zuletzt bearbeitet:
@Kachelator
Da hast du recht, vielleicht hätte ich vorher mal einen Blick in die MSDN werfen sollen.
Ich wusste nicht, daß die DeleteItem() nicht virtuell ist.
Naja ich weiß aber warum ich die MFC nicht so gern mag *g*.

Gruß Homer
 

Neue Beiträge

Zurück