PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Suche Logikfehler ...


x-dragon
2003-06-10, 16:05:53
Hab gerade ein kleines Problem mit einem Delphi-Programm, aber das Problem ist eher logischer Natur.

Ich arbeite gerade an einer Art Terminplaner und habe eine ListViewBox mit xxx Einträgen. In dieser Liste sind die Uhrzeiten von z.B. 0600-2000 eingetragen (im 10 Minuten-Takt).

Jetzt können aber nicht nur die Daten von einer Person angezeigt werden sondern auch z.B. 5 gleichzeitig (sind sortiert nach Uhrzeit und dann nach Nr. der Person[1..5]), also wie im Anhang zu sehen ist.

Jetzt möchte ich gerne die Einträge in unterschiedlichen Farben anzeigen lassen, damit man sie besser auseinanderhalten kann. Dies kann ich aber nur während des Zeichenvorgangs der Tabelle(bzw der aktuellen Zeile) machen in der ich nur die aktuelle Position abfragen kann und die Personen die angezeigt werden sollen (Daten können ja erst später eingetragen werden) und dieser Zeile dann die passende Farbe zuweise. Allerdings kann es auch sein das nur Person 1, 3 und 5 angezeigt werden soll ...

Und so sieht mein aktueller Versuch aus:
procedure TFmHaupt1.ListViewCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
{********************************************************************}
var
i : Integer;
lv : TListView;
pers : TStrings;
begin
lv := TListView(Sender); // wird für mehrere Listen genutzt
pers := TStringList.Create;

for i := 1 to 5 do
if sets[i] then // sets : array[1..5] of Boolean - welche Sets/Personen
pers.Add(IntTostr(i)); // StringListe der angezeigten Personen(Nr.)

with lv.Canvas.Brush do
begin
for i := 1 to pers.Count do
if (Item.Index + 1) mod i = 0 then
if sets[StrToInt(pers[i-1])] then
case i of
1: Color := clInfoBk;
2: Color := clInactiveCaptionText;
3: Color := clScrollBar;
4: Color := clMoneyGreen;
5: Color := clMenu;
end;

end;
end; Das Ergebnis sieht auch schon schön bunt aus, aber leider sind die Farben nicht den entsprechenden Personen zugeordnet(s. auch Anhang).

Gebt mir mal einen kleinen (oder auch größeren) Tip, wo mein Denkfehler liegen könnte.

x-dragon
2003-06-10, 16:09:39
War zurest der falsche Anhang und ändern konnte ich ihn nicht mehr ??? Naja hier ist der richtige:

Demirug
2003-06-10, 17:11:15
Also ich bin ja kein Delphiexperte aber in C++ und C# kann man jedem Listview Eintrag auch noch Custom Daten zuweisen die man dann im CustomDraw benutzten kann. Wenn das auch in Delphi geht könnte man die Farbe einfach dort speichern und sich den ganzen Hickhack sparen.

Ich bin mir jetzt nicht sicher on ich die Problemsetellung richtig verstanden haben. Also für mich nochmal zur klärung.

- Jede Person hat eine eigene Farbe
- Es können 1 - 5 Personen gleichzeitig angezeigt werden.
- Jede Kombination von Personen ist zulässig
- Wird eine Person angezeigt wird sie für alle Zeiten angezeigt.

Stimmt das so?

Xmas
2003-06-10, 18:17:25
X-Dragon,

möchtest du für jede Person eine unterscheidbare Farbe (also bei 3 Personen bekommt die erste, egal wer, immer Blau z.B.), oder auch eine feste Farbe (also Person 3 immer Grün z.B.)?


Ersteres löst du so:

with lv.Canvas.Brush do
begin
i := Item.Index mod pers.Count;
case i of
0: Color := clInfoBk;
1: Color := clInactiveCaptionText;
2: Color := clScrollBar;
3: Color := clMoneyGreen;
4: Color := clMenu;
end;
end;


Zweites so:

with lv.Canvas.Brush do
begin
i := Item.Index mod pers.Count;
case StrToInt(pers[i]) of
0: Color := clInfoBk;
1: Color := clInactiveCaptionText;
2: Color := clScrollBar;
3: Color := clMoneyGreen;
4: Color := clMenu;
end;
end;


Beides geht davon aus dass Item.Index und pers[] 0-basiert sind.

x-dragon
2003-06-10, 20:18:08
Original geschrieben von Demirug
Also ich bin ja kein Delphiexperte aber in C++ und C# kann man jedem Listview Eintrag auch noch Custom Daten zuweisen die man dann im CustomDraw benutzten kann. Wenn das auch in Delphi geht könnte man die Farbe einfach dort speichern und sich den ganzen Hickhack sparen.

Ich bin mir jetzt nicht sicher on ich die Problemsetellung richtig verstanden haben. Also für mich nochmal zur klärung.

- Jede Person hat eine eigene Farbe
- Es können 1 - 5 Personen gleichzeitig angezeigt werden.
- Jede Kombination von Personen ist zulässig
- Wird eine Person angezeigt wird sie für alle Zeiten angezeigt.

Stimmt das so? Hmm, das werd ich mir mal noch genauer anschauen ...

Ja, jede Person soll eine eigene Farbe haben und es können 1 - 5 Personen gleichzeitig angezeigt werden, in unterschiedlichen Kombinationen (das hängt damit zusammen das auch frei definierbare Zeitrahmen für jede Person möglich sind).

Wie meinst du das denn, für alle Zeit anzeigen? Im Setup kann die Anzeige individuell angepaßt werden, also die möglichen anzeigbaren Personen ausgewählt werden, und dies wird anschliessend bei der folgenden Aktualisierung entsprechend umgesetzt.

Original geschrieben von Xmas
X-Dragon,

möchtest du für jede Person eine unterscheidbare Farbe (also bei 3 Personen bekommt die erste, egal wer, immer Blau z.B.), oder auch eine feste Farbe (also Person 3 immer Grün z.B.)?

Ersteres löst du so:
...

Zweites so:
...
Beides geht davon aus dass Item.Index und pers[] 0-basiert sind. Wie so einfach soll das sein? Super danke :up:, werd das gleich mal morgen früh testen ...

Also wie schon oben geschrieben soll jede Person seine eigene Farbe haben.

Xmas
2003-06-10, 20:32:00
Original geschrieben von X-Dragon
Wie so einfach soll das sein? Super danke :up:, werd das gleich mal morgen früh testen ...
Ja sicher ist das so einfach ;)
Mit der StringList zählst du ja wieviele Personen angezeigt werden sollen, und alle soviele Items fangen ja die Farben wieder von vorne an. Also Item.Index mod pers.Count.
Und die Verbindung zwischen Position der Person und Nummer der Person stellt ja die StringList dar.

Übrigens ist es noch besser, wenn du die Case-Anweisung mit einem Array von Farben ersetzt und i als Index in das Array nimmst.

x-dragon
2003-06-10, 21:03:18
Original geschrieben von Xmas
..
Übrigens ist es noch besser, wenn du die Case-Anweisung mit einem Array von Farben ersetzt und i als Index in das Array nimmst. Da hast du recht, das optimieren kommt aber erst dran wenn es soweit läuft. Die StringListe z.B. muss ich ja auch nicht unbedingt für jede neuzuzeichnende Zeile neu erstellt und gefüllt werden :).

x-dragon
2003-06-11, 09:53:54
procedure TFmHaupt1.LVCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
{********************************************************************}
var
lv : TListView;
begin
lv := TListView(Sender);

with lv.Canvas.Brush do
Color := LVColor[StrToInt(pers[Item.Index mod pers.Count])];
end; Hmm, sieht schon ein wenig kürzer aus :stareup: und funktioniert einwandfrei, danke nochmal :).

Gast
2003-06-11, 11:53:17
Original geschrieben von X-Dragon
procedure TFmHaupt1.LVCustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
{********************************************************************}
var
lv : TListView;
begin
lv := TListView(Sender);

with lv.Canvas.Brush do
Color := LVColor[StrToInt(pers[Item.Index mod pers.Count])];
end; Hmm, sieht schon ein wenig kürzer aus :stareup: und funktioniert einwandfrei, danke nochmal :).

np ich helf immer wieder gerne ;)