Autor Beitrag
padawan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Do 09.12.10 14:08 
Guten Tach, Delphifreunde!

Wenn ich per MonthCalendar ein Datum auswähle, sollen alle die Einträge der Lv gelistet werden, die das eben angeklickte Datum enthalten, diese am besten zusammenrücken u. in der Lv oben sichtbar machen. Soweit bin ich: Die sichtbaren Einträge mit dem betr. Datum werden selektiert u. farblich hervorgehoben. Klappt aber nur, wenn in der Lv der erste Eintrag[0] ganz oben sichtbar ist. Sowie die Liste nur einmal scrollt, werden die falschen items markiert. Also beginnt die Zählung der items immer mit Null(relativ)- bei meinen 18 Einträgen 0-17, auch nach scrollen der Lv. Gibt es nicht eine Möglichkeit, den absoluten Index der Einträge zu erfahren? Damit würde ich immer treffen, unabhängig vom Scrollen. Oder muss ich beim Selektieren vorher berechnen, wieviel Zeilen oben nicht sichbar sind?

Danke Euch im Voraus!!! Gruß Uli
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 09.12.10 14:14 
Warum ist das selektieren der Items von der Scrollposition abhängig? Wie selektierst du denn?

Für mich hört sich das so an, als könnte man da das Konzept optimieren. Also die Daten im Hintergrund behalten und die Listview immer so füllen/leeren, wie es der Nutzer gerne hätte.

_________________
We are, we were and will not be.
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Do 09.12.10 19:45 
Hallo Gausi!

Ich selektiere mit ...selected:=True; Das funzt auch. Aber eben nur, wenn oben der Eintrag[0] der Liste angezeigt wird. Ansonsten selektiere ich die falschen Einträge, denn der obere Eintrag ist immer 0, auch wenn es z.B. der 5. Eintrag ist. Das kann man sicher berechnen. Ich denke mit: Index:=oberster Eintrag + die Einträge, welche noch vor dem oberen Eintrag(unsichtbar) sind. Vielleicht kann man das gut mit der vertikalen Scrollbar machen? Wenn diese, je nach ihrer Position bestimmte Werte liefert? Unter TP7 habe ich mir meine Listen zu Fuß programmiert und das klappte immer sehr gut. Es führen natürlich mehrere Wege zum Ziel, dachte, es gibt eine einfache Lösung.
Wie Du schon schreibst: Das kann man ganz sicher optimieren!
DANKE Dir!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 09.12.10 20:57 
user profile iconpadawan hat folgendes geschrieben Zum zitierten Posting springen:
Ich selektiere mit ...selected:=True; Das funzt auch. Aber eben nur, wenn oben der Eintrag[0] der Liste angezeigt wird.
Genau da liegt das Problem, aber den Code hast du genau nicht gepostet... :roll:
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.12.10 12:14 
Hallo,

hier der code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
procedure TForm1.MonthCalendar1Click(Sender: TObject);
var i: integer;
    Value : TListItem;
    s: string;
begin _i:=0// Global(integer)
Datum.Text := FormatDatetime('dd.mm.yyyy',MonthCalendar1.Date);
_CalendarClick:=True; //Globale Var(in CustomDraw verwendet)
Value := tListitem.Create(listview1.items); _item
for I := 0 to ListView1.Items.Count - 1 do
    begin
    if ListView1.FindCaption (0,Datum.Text,true,true,true) <> nil then
       begin
       s:=(ListView1.items.item[i].Caption);
       Value := ListView1.FindCaption (0,Datum.Text,true,true,true);
       if (Value <> Nil)  And (value.caption=s) then
          begin _items[i]:=True; // Global(_items)
          Label2.Caption := '<'+Value.caption+'>'// Nur zur Kontrolle
          showmessage('<'+IntToStr(i)+'>  '+ListView1.items.item[i].Caption+
                      '  <'+BoolToStr(_items[i])+'>');
          end else _items[i]:=False;
       end;
    end;
ListView1.Invalidate;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if (_CalendarClick) And (_items[_i]) then
   ListView1.Canvas.Brush.Color:=clGreen
   else
   if Odd(Item.Index) then
      ListView1.Canvas.Brush.Color:=clSilver;
      else ListView1.Canvas.Brush.Color:=clWindow;
inc(_items[_i]);
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 10.12.10 12:44 
Ich sehe keinen Code zum Selektieren. :nixweiss:
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.12.10 13:30 
Ja, habe versehentlich alte Procs gezeigt.
Beim Start selektiere ich den letzten Eintrag(hier 2. ListView-Seite), das klappt sehr gut:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
procedure TForm1.FormShow(Sender: TObject);
begin
if (_NoBeleg=False) And (_CalendarClick=False) then
   begin 
   //ListView1.Items[_Belege-1].Selected := TRUE; // _Belege(Global) = Anzahl(Einträge)
   //ListView1.Items[_Belege-1].MakeVisible(False); // auskommentiert, denn nur diese Ansicht zeigt alles fehlerfrei
   ListView1.SetFocus;
   end;
end;

procedure TForm1.MonthCalendar1Click(Sender: TObject);
var i: integer;
    Value : TListItem;
    s: string;
begin _i:=0for i:=0 to 500 do _items[i]:=False;
Datum.Text := FormatDatetime('dd.mm.yyyy',MonthCalendar1.Date);
_CalendarClick:=True; //Globale Var
Value := tListitem.Create(listview1.items);
for I := 0 to ListView1.Items.Count - 1 do
    begin
    if ListView1.FindCaption (0,Datum.Text,true,true,true) <> nil then
       begin
       s:=(ListView1.items.item[i].Caption);
       Value := ListView1.FindCaption (0,Datum.Text,true,true,true);
       if (Value <> Nil)  And (value.caption=s) then
          begin _items[i]:=True;
          Label2.Caption := '<'+Value.caption+'>';
          ListView1.Items[i].Selected := TRUE;
          end else _items[i]:=False;
       end;
    end;
ListView1.Invalidate;
Summe.SetFocus;
end;

procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if (_CalendarClick) And (_items[_i]) then
   begin
   ListView1.Canvas.Brush.Color:=clGreen;
   {if (ListView1.Items[_i].Selected) then
       hier alle selektierten items nach oben(Top) verschieben?? Und in FormShow alle=MakeVisible??}

   end else
       if Odd(Item.Index) then
          ListView1.Canvas.Brush.Color:=clSilver
          else ListView1.Canvas.Brush.Color:=clWindow;
inc(_i);
end;


Ich denke, würde es hinbekommen, mir fehlt der Ansatz zum Feststellen vom tatsächlichen item.Index!
Zeigt die Liste oben am Anfang den ersten(!) Eintrag der Liste, also die vertikale ScrollBar steht ganz oben, dann werden alle die Zeilen grün dargestellt, die dem gew. Datum entsprechen und die gerade in der ListView sichtbar sind. Sowie ich runter scolle und die vertikale ScrollBar nicht mehr ganz oben ist, werden, dem Vorkommen vom gewählten Datum nach, anzahlmäßig richtig, aber die falschen Zeilen markiert, nähmlich alle um eine(wenn Top[1]) oder um zwei(wenn Top[2]) zu weit unten. Der Item.Index der sichtbaren Items beginnt ja immer(!) mit Null, egal, wohin das Lv-Fenster gescrollt ist.
Gibt es die Möglichkeit, die vert. ScrollBar abzufragen?? Und diesen Wert in die Berechnung mit einzubringen?

Habe 2 dicke Bücher: Delphi 6 & Delphi in Team, nix! Auch über Google findet sich vieles, nur nicht darüber.

DANKE Dir vielmals!


Zuletzt bearbeitet von padawan am Fr 10.12.10 13:36, insgesamt 2-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 10.12.10 13:33 
Du findest mit FindCaption einen Eintrag und greifst dann auf das Item mit Index i zu statt auf das gefundene...
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 10.12.10 13:39 
Ich glaube, ich hab den Fehler: Ein _total_ verkorkstes Konzept. :mrgreen:

Du nimmst die globale Variable "_i", um im OnPaint die Zellen anders zu markieren. Im OnPaint veränderst du _i, und veschurbelst das globale _i mit dem ItemIndex. OnPaint wird aber nur für sichtbare Elemente aufgerufen, daher stimmt das _i nicht mit dem angezeigten Item-Indizes überein.

Zitat:
Der Item.Index beginnt ja immer(!) mit Null, egal, wohin das Lv-Fenster gescrollt ist.
Das ist daher falsch - nur dein _i beginnt bei Null.

Lass das OnPaint einfach mal weg, das Gehampel mit dem _i auch und lass Windows die selektierten Einträge anders darstellen. Oder überprüfe im OnPaint nicht auf _i, sondern darauf, ob das zu malende Item selektiert ist oder nicht.

_________________
We are, we were and will not be.
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.12.10 13:48 
Hallo Gausi, denke, ich verstehe, was Du meinst. Demnach sollte ich vor(!) dem Neuzeichnen, in CalendarClick die gefundenen Einträge selektieren und(!) gleich toppen(item.insert[0])? Dann würden im CustomDraw die gefundenen Einträge alle berücksichtigt.. Gelle?? Werde es mal umsetzen. Melde mich!
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.12.10 13:52 
Hallo jaenicke!

Verstehe nicht ganz, wie Du das meinst:
<Du findest mit FindCaption einen Eintrag und greifst dann auf das Item mit Index i zu statt auf das gefundene...>
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 10.12.10 13:55 
Du solltest dringend von dieser Technik wegkommen, da du nicht wirklich kontrollieren kannst, wann und wie oft das OnPaint aufgerufen wird. Damit wird deine Anzeige immer wieder mal Unsinn anzeigen - z.B. dann, wenn die ListView mal ganz oder teilweise von einem anderen Fenster verdeckt wird und danach teilweise neugezeichnet werden muss.

So wie es für mich aussieht, hast due Datenspeicherung und -anzeige sehr stark miteinander verwoben - das sollte aber immer getrennt voneineander sein. Wenn du die Daten von der Anzeige trennst, hast du auch keine Probleme mehr mit "gefundene Einträge toppen". Du zeigst dann einfach nur diese an, und nichts weiter. Und wenn der User wieder alle Daten sehen will, füllst du wieder alles in die ListView.

_________________
We are, we were and will not be.
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: Fr 10.12.10 14:13 
Ja, es kommen wohl immer wieder meine TP7-Zeiten durch, sicher mache ich einiges falsch. Fehlerhafte Anzeigen kommen tatsächlich immer wieder. Werde mich noch reinknien. Melde mich wieder, wenn klappt!
DANKE Euch beiden!!!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 10.12.10 14:38 
Wie schon geschrieben wurde ist das ganze Konzept der Umsetzung schlecht, aber was ich speziell meinte ist:
user profile iconpadawan hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
       Value := ListView1.FindCaption (0,Datum.Text,true,true,true);
       if (Value <> Nil)  And (value.caption=s) then
          begin _items[i]:=True;
          Label2.Caption := '<'+Value.caption+'>';
          ListView1.Items[i].Selected := TRUE;
Du suchst vom ersten Eintrag ab den ersten passenden Eintrag (findest also immer den selben Eintrag). Und dann markierst du den i-ten Eintrag. :eyecrazy: :nut:
padawan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 35
Erhaltene Danke: 1



BeitragVerfasst: So 12.12.10 12:16 
Habe weitgehend verstanden, woauf es ankommt. Und einige wichtige Dinge gelernt! Klappt jetzt schon viel besser!
DANKE Euch vielmals! :!: