Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Widerwillige Spalte in einer ListView Kompo (https://www.delphipraxis.net/1347-widerwillige-spalte-einer-listview-kompo.html)

phlux 16. Nov 2002 09:53


Widerwillige Spalte in einer ListView Kompo
 
Hallo!
Ich habe folgendes Problem, in einem meiner Programme hab ich eine TListView Kompo, diese ist hat den Style vsReport und nur eine Spalte, dem entsprechend sollte die Spalte so breit wie die TListView sein. Mit dem Objektinspektor lässt sich das wie folgt realisieren:
1. ViewStyle auf vsReport setzten
2. Unter Columns eine neue Spalte hinzufügen
3. Dieser Spalte eine Caption geben
4. AutoSize dieser Spalte auf True setzen

So, wenn ich das ganze jetzt jedoch durch Quellcode verwirklichen will sieht das wie folgt bei mir aus:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var Col: TListColumn;

begin
  With ListView1 do
  begin
    ViewStyle := vsReport;
//    ColumnClick := False;
//    RowSelect := True;
    Col := Columns.Add;
    Col.MaxWidth := 0;
    Col.MinWidth := 0;
    Col.Width := 50;
    Col.Caption := 'C:\';
    Col.AutoSize := True;
  end;
end;
Hat jedoch als Ergebniss nicht den gewünschten Effekt, die somit erzeugte Spalte ist viel kleiner als erwünscht, hab ich da irgendetwas übersehn, oder wo liegt mein Fehler??? Hoffe ihr könnt mir helfen. :(

[edit=Admin]Neue Delphicode-Tags eingefügt. Mfg. Daniel[/edit]

Christian Seehase 16. Nov 2002 11:05

Moin Phlux,

also ich behelfe mir da immer so (Beispiel);

Delphi-Quellcode:
aiColWidth[0] := Max(aiColWidth[0],Canvas.TextWidth(ListView1.Items[ListView1.Items.Count-1].Caption)+16);
Wobei aiColWidth eine Tabelle ist (aiColWidth = a Array / i integer), die die Spaltenbreiten aller Spalten enthält. Initialisiert wird diese mit den Breiten der Überschriften, so das diese immer lesbar sind.
Sobald alle neu hinzuzufügenden Zeilen eingetragen wurden, werden dann die Werte aus der Tabelle den Spaltenbreiten zugeordnet.

Daniel B 16. Nov 2002 11:19

Hallo phlux,

ich glaub, da muss man erst einen entsprechend langen String einfügen, damit das AutoSize wirkung zeigt. //Könnte aber auch ein Schmarrn sein, hatte selbst mal vor nem Jahr so ein Problem

Grüsse, Daniel :hi:

phlux 17. Nov 2002 12:57

Zitat:

Zitat von Christian Seehase
Wobei aiColWidth eine Tabelle ist (aiColWidth = a Array / i integer), die die Spaltenbreiten aller Spalten enthält. Initialisiert wird diese mit den Breiten der Überschriften, so das diese immer lesbar sind.
Sobald alle neu hinzuzufügenden Zeilen eingetragen wurden, werden dann die Werte aus der Tabelle den Spaltenbreiten zugeordnet.

Also diese aiColWidth, ist einfach nur ein (unbestimmter) Array vom Typ Integer? Ich denke mal für nur eine Spalte kann ich das auch noch mit ner einfachen Integer-Variable machen. Danke!

Zitat:

Zitat von Daniel B
ich glaub, da muss man erst einen entsprechend langen String einfügen, damit das AutoSize wirkung zeigt. //Könnte aber auch ein Schmarrn sein, hatte selbst mal vor nem Jahr so ein Problem

Anscheinend nicht, das ist ja mein Problem, wenn ich im ObjektInspektor für die Column nur 'C:\' eingebe hat sie die komplette breite der ListView, wenn ich das versuche durch code hinzukriegen hauts net hin :(

Christian Seehase 17. Nov 2002 13:07

Moin Phlux,

logisch, bei einer Spalte genügt natürlich auch ein Wert.
Je nachdem, wieviele Zeilen der Listview bekommen soll, wäre es ganz sinnvoll vor dem Füllen Listview.Items.BeginUpdate, und wenn alles eingetragen, und die Spaltenbreite angepasst ist ListView.Items.EndUpdate aufzurufen.
Das bringt, gerade bei vielen Einträgen, einen ziemlichen Geschwindigkeitsvorteil.

Ach ja. Die maximale Breite (in Zeichen gerechnet) sollte 259 nicht übersteigen. Die Spalte wird dann zwar breiter, aber es wird trotzdem nicht alles angezeigt.

phlux 17. Nov 2002 13:22

Zitat:

Zitat von Christian Seehase
Je nachdem, wieviele Zeilen der Listview bekommen soll, wäre es ganz sinnvoll vor dem Füllen Listview.Items.BeginUpdate, und wenn alles eingetragen, und die Spaltenbreite angepasst ist ListView.Items.EndUpdate aufzurufen.
Das bringt, gerade bei vielen Einträgen, einen ziemlichen Geschwindigkeitsvorteil.

Echt? Cool, das wusste ich nicht, hab mich immer schon gewundert, wozu man das braucht, hab es in den meisten fällen auch weggelassen, da es auch ohne lief

Zitat:

Ach ja. Die maximale Breite (in Zeichen gerechnet) sollte 259 nicht übersteigen. Die Spalte wird dann zwar breiter, aber es wird trotzdem nicht alles angezeigt.
Hmm, ich brauch das ja für meine Kompo mit der ich den Verzeichnisinhalt auslesen kann, da theo. die länge eines verzeichnisses eh nicht 255 zeichen überschreiten darf dürfte es kein problem geben mit der Begrenzung.

iaby 2. Dez 2002 15:41

wie kann ich denn in die verschiedenen columns von der listview schreiben?
ich will dort einfach nur einen text, bsp: "hallo" in der zweiten spalte, einfügen!

gruß,
iaby

Christian Seehase 2. Dez 2002 16:00

Moin iaby,

als erstes wirst Du mal auf die Eigenschaft ViewStyle auf vsReport umstellen müssen, um überhaupt die Spaltenansicht zu erhalten.

Mit

Delphi-Quellcode:
ListView1.Items.Add;
wird dann eine neue Zeile hinzugefügt, und mit

Delphi-Quellcode:
ListView1.Items[ListView1.Items.Count-1].Caption := '.....';
wird dann der Text der 1. Spalte eingetragen (oder auch '' wenn dort nichts stehen soll).

Die weiteren Spalten sind dann die Subitems, die Du mit

Delphi-Quellcode:
ListView1.Items[ListView1.Items.Count-1].SubItems.Add('und hier der Text');
hinzufügen kannst. Das erste SubItem hat dann den Index 0. Ein erneutes Hinzufügen eines SubItems zu einem speziellen Item fügt dann wieder einen Eintrag eine Spalte weiter ein.
Nicht zu vergessen vorher die Columns zu erzeugen, sonst wirst Du nicht viel von den SubItems sehen.

phlux 2. Dez 2002 16:49

Also ich würde zuerst ein TListItem deklarieren und es dann mit

Delphi-Quellcode:
Var Item: TListItem;

begin
  //...
  Item := TListView.Items.Add;
end;
hinzufügen, das erleichtert einem den Zugriff auf das Item extrem wenn man nacher noch die Eigenschaften (Caption zum Bleistift) umändern will :)

(ich wäre dafür man splittet das thema auf ;) )

iaby 2. Dez 2002 17:16

ich will eine playliste erstellen(wie es sie auch im winamp oder sonst wo gibt).
dazu brauche ich:
-3spalten: Nummer/Filename/Länge
-später will ich die caption der verschiedenen spalten wieder auslesen(eigentlich nur der Nummer, damit ich auf einen array mit den filenamen zugreifen kann, um das lied abzuspielen)
ich denke mal, das müsste mit der TListView zu machen sein!

eine frage noch zu eurer erklärung: wo steht nun der index der spalte(0,1,2)?
konnte ich leider nicht dem post entnehmen :oops:

Daniel B 2. Dez 2002 17:57

Hi,

Caption ist die erste Spalte, die anderen werden mit SubItems[i] bezeichnet. 0 Wäre die zweite, 1 die dritte usw.
Beim Einfügen von Items, könntest Du noch ein zusätzliches Item einfügen und zwar mit dem ListView.Items.Count -1, somit hättest DU auch gleich einen Index, womit Du dann auf ein Array zugreifen kannst.

Grüsse, Daniel :hi:

phlux 2. Dez 2002 18:05

Zitat:

Zitat von iaby
später will ich die caption der verschiedenen spalten wieder auslesen(eigentlich nur der Nummer, damit ich auf einen array mit den filenamen zugreifen kann, um das lied abzuspielen)
ich denke mal, das müsste mit der TListView zu machen sein

Dazu brauchst du nicht extra die Spaltennummer herausfinden, falls du MultiSelect auf False gesetzt hast bei deiner TListView, kannst du ganz einfach über die Eigenschaft TListView.Selected an das markierte Item drankommen (mit Untereigenschaften->SubItems, für die Pfadangabe), willst mit MultiSelect := True arbeiten solltest du in einer Schleife alle Items abfragen ob sie Selected = True sind, falls ja kannst du dann über die Eigenschaft SubItems auch dort den Pfad auslesen ;)

iaby 3. Dez 2002 08:08

Danke!
 
ich habs jetzt so weit mal hinbekommen!
das aktuell markierte lese ich mit itemindex aus!
funktioniert mal recht gut, problem hab ich dann nachher aber, wenn ich ein item lösche oder eins dazu füge: dann muss ich die ganzen captions ändern und außerdem noch den array neu sortieren! ich hoffe mal das braucht nicht zu viel rechenleistung :?

wirklich vielen dank, habt mir alles ehr geholfen!!!

Christian Seehase 3. Dez 2002 10:10

Moin iaby,

Zitat:

Zitat von iaby
...wenn ich ein item lösche oder eins dazu füge: dann muss ich die ganzen captions ändern...

Schau Dir doch mal die Methode

Delphi-Quellcode:
ListView1.Items.Delete(...);
an.

iaby 3. Dez 2002 10:21

das schon, aber ich habe ja in der ersten spalte die position durchnummerriert. außerdem muss ich den array neu sortieren :-(

Christian Seehase 3. Dez 2002 10:31

Moin iaby,

stimmt natürlich.
Wenn Du berücksichtigst, dass bis zur Stelle an der eingefügt/gelöscht wird, sich nichts an der Nummerierung geändert haben kann, also nur noch ab dieser Stelle Änderungen durchgeführt werden müssen, sparst Du schon mal Zeit.
Wenn Du beim Einfügen die Zeilen gleich an der richtigen Stelle einfügst, sparst Du Dir auch das Sortieren.

phlux 3. Dez 2002 14:25

Zitat:

Zitat von iaby
das schon, aber ich habe ja in der ersten spalte die position durchnummerriert. außerdem muss ich den array neu sortieren :-(

Falls in der ListView der identische Inhalt wie im Array steht kannst du auch gleich die Sachen einfach aus der ListView auslesen, ist doch am einfachsten so :?

Daniel B 3. Dez 2002 15:54

Hallöle,

ListView.DeleteSelected; ist Dir hoffentlich schon in die Finger gekommen.

Hier ist mal ein Prozedur von mir, wie man den Inhalt im Array nachrutscht.

Du musst nur wissen, bevor Du was nachrutsch, welche Einträge Du gelöscht hast.

Delphi-Quellcode:
procedure TMainFormMC2004.ButtonKKLokLoeschenClick(Sender: TObject);
//Markierte einträge aus der Liste entfernen -> KK Lok
var
  i, n, t: integer;
begin
  if ListViewKKLok.SelCount = 1 then //Nur wenn ein Eintrag ausgewählt ist
  begin
    i := StrToInt(ListViewKKLok.Selected.SubItems[5]);
    for n := i +1 to MC2004.MenueInit.LokAnzahl -1 do //Array nachrücken
    begin
      MC2004.MenueInit.LokStamm[n -1] := MC2004.MenueInit.LokStamm[n];
    end;
    MC2004.MenueInit.LokAnzahl := MC2004.MenueInit.LokAnzahl -1; //Array kürzen
    for t := 0 to ListViewKKLok.Items.Count -1 do //Restliche Indexe -1
    begin
      if StrToInt(ListViewKKLok.Items.Item[t].SubItems[5]) > i then
      begin
        ListViewKKLok.Items.Item[t].SubItems[5] := IntToStr(StrToInt(
          ListViewKKLok.Items.Item[t].SubItems[5]) -1);
      end;
    end;
  end;
  LVLokFuellen;
  EditKKLokID.Clear;
  EditKKLokName.Clear;
  EditKKLokAdresse.Clear;
  EditKKLokTraeg.Clear;
  EditKKLokBeschl.Clear;
  EditKKLokVerzoeg.Clear;
  EditKKLokID.SetFocus;
  Check;
end;
Anschliessend musst Du nur noch den Inhalt des Arrays entweder neu in die LV eintragen, oder Du lässt es bleiben. Mit der Geschwindigkeit wirst Du da keine Probleme, behaupte ich jetzt einfach mal, also ich merke bei 200 Einträgen, jeder mit 6 SubItems überhaupt nichts.

Grüsse, Daniel :hi:

iaby 3. Dez 2002 16:55

danke, sehr hilfreich deine procedure!!!
werd das dann mal einbauen, und auch mal testen!
Zitat:

Falls in der ListView der identische Inhalt wie im Array steht kannst du auch gleich die Sachen einfach aus der ListView auslesen, ist doch am einfachsten so
ist aber leider nicht so :(
kann man irgendwie verhindern, dass man die spalten der listview vergrößern kann?
ich hab mal maxwidth und minwidth auf 50 gestellt, aber verschieben kann man die immer noch, nur springen sie dann auf den ursprung wieder zurück!
ist aber nur eine kleinigkeit, nicht so schlimm :wink:

Iaby


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz