Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - ListView, *edit* SubItem editieren?


sahib - Mi 13.04.05 21:10
Titel: ListView, *edit* SubItem editieren?
Moin.

Ich habe eine ListView mit Style := vsReport. Jetzt würde ich ganz gerne wissen, auf welche Caption respektive auf welches SubItem geklickt wurde. Mit Hilfe folgender Zeilen bekomme ich die Mausposition und die gewählte Zeile heraus. Nur wie ermittel ich das SubItem?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  if Item = nil then Exit;
  ShowMessage(Item.Caption);
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MouseX := X; MouseY := Y
end;

Ich habe gedacht, dass ich die Breiten der Spalten notiere (Columns.Item[x].Width) und dann zur relativen Muasposition das SubItem herausbekomme. Das geht natürlich nur, WidthType = -2 ist.

Hat das schon mal jemand so gemacht, oder gibt es eine einfachere, sprich elegantere, Möglichkeit?

*EDIT*
Mir ist eingefallen, dass man Ingeneuren auch nicht Teillösungen vorgeben sollte, sondern einfach nur das Ziel nennt. Daher: Ich wollte gerne die SubItems in einer ListView editieren und nicht nur die Caption. Also, wer da etwas anderes weiß, als angesprochene Lösung... ;)

Grüße,
Christian


Lannes - Mi 13.04.05 21:44

Hallo,

auch wenn WidthType = -2 oder -1 ist kannst Du doch die Spaltenbreiten abfragen.
Anmerkung: Spaltenbreitenabfrage geht nicht innerhalb BeginUpdate und EndUpdate.

Zusätzlich zu den Spaltenbreiten noch ListView1.Items[0].Item.Left berücksichtigen,
falls die Spalten nach links gescrollt wurden.

Zitat aus der Delphi-Hilfe:
Die Eigenschaft Left legt die horizontale Koordinate des linken Randes eines Listeneintrags relativ zur Listenansicht fest. Die Angabe erfolgt in Pixel.


sahib - Mi 13.04.05 23:34

Hi.

Alles iO. Hat geklappt. Schade, dass die TListView nicht standardmäßig das Editieren der SubItems zulässt. So musste ich mir über diesen Umweg ein Edit-Feld darauf legen.

Christian


MeisterB - Di 24.05.05 14:13

Sahib könntest du bitte mal den Code zur Positionierung der Editbox posten?

Danke im Voraus!


Tino - Di 24.05.05 14:29

user profile iconsahib hat folgendes geschrieben:
Schade, dass die TListView nicht standardmäßig das Editieren der SubItems zulässt. So musste ich mir über diesen Umweg ein Edit-Feld darauf legen.

Diese Möglichkeit habe ich auch in einem meiner Projekt benötigt. Ich bin dann auf die Virtual TreeView [http://www.soft-gems.net/VirtualTreeview/] umgestiegen. Diese bietet schon von sich aus dieses Feature an.

Gruß
Tino


sahib - Di 24.05.05 20:51

Moin.

@Tino: Kenne ich auch, ist mir aber für ein kleines Projekt zu groß. Zumal der XP-Styles wegen.

@Meister: Ist Dein Name Programm? ;)

Vielleicht nicht besonders schön, aber es funktioniert. Um den Rest, schließen des Edit-Feldes und Eintragen in ListView, musst Du Dich selber kümmern. Ich speichere solche Daten sonst nicht in der Form ab, sondern verwalte die Daten selber.

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:
procedure TForm1.ListView1Click(Sender: TObject);
var
  LI           : TListItem;
  Spalte, i    : Byte;
  VorherigeSpaltenBreite,
  SpaltenBreite: Integer;
  ARect: TRect;
  Edit : TEdit;
begin
  with ListView1 do begin
    LI := Selected;
    if LI = nil then Exit;

    ARect := LI.DisplayRect(drLabel);

    SpaltenBreite := 0;
    for i := 0 to Pred(Columns.Count) do begin
      VorherigeSpaltenBreite := SpaltenBreite;
      inc(SpaltenBreite, Columns.Items[i].Width);
      if PosX <= SpaltenBreite then begin
        Spalte := i;
        Break
      end
    end;

    Edit := TEdit.Create(Self);
    with Edit do begin
      Left := VorherigeSpaltenBreite;
      Top := ARect.Top;
      Width := SpaltenBreite - VorherigeSpaltenBreite;
      Height := ARect.Bottom;
      if Spalte = 0 then
        Text := LI.Caption
      else
        Text := LI.SubItems[Pred(Spalte)];
      Parent := ListView1
    end
  end
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  PosX := X
end;


Viele Grüße,
Christian