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 ListView Columns aus- und einblenden (nicht width=0!) (https://www.delphipraxis.net/93171-listview-columns-aus-und-einblenden-nicht-width%3D0.html)

neothemachine 1. Jun 2007 16:44


ListView Columns aus- und einblenden (nicht width=0!)
 
Hallo liebe Delphianer....

mein Ziel ist es ListViews zu haben, bei denen Spalten ein- und ausgeblendet werden können per Rechtsklick auf die Spalten mit einem Kontextmenü, so wie auch beim Windows Explorer oder wo auch immer. Im Forum gibts schon einen Thread dazu, der aber den Weg mit Column width=0 geht, was ich aber ziemlich blöd finde, da man dann die Spalten nicht mehr in der Breite anpassen kann, da man dann die "versteckte" Spalte wieder auseinanderzieht..

Diese Seite sah ja schon ganz vielversprechend aus, aber wie man in den Comments unten lesen kann, ist es auch nicht das wahre. Ich hab das auch mal ein bisschen getestet und es werden tatsächlich die falschen Spalten mit Daten befüllt wenn man nach dem Entfernen einer Spalte noch neue Daten hinzufügt.

Allerdings hat dort in den Kommentaren ein "Scotty B" geschrieben:
Zitat:

As far as I know, this is a problem with the .NET ListView control. It seems there is no straight forward way to hide columns. This was possible in the Win32 Common Control that this wraps, but that functionality was not passed on in .NET.
Also muss es ja irgendeinen Weg für Delphi Win32 geben, vorallem da es ja auch bei vielen anderen Programmen geht...

Hat nun irgendjemand eine Idee, nen Tipp? Irgendwas?

Maik

DGL-luke 1. Jun 2007 16:49

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Naja, die Winforms Controls sind letztendlich ein Wrapper um die Win32-Fensterklassen/Controls.

Du könntest rein theoretisch darauf zugreifen. Dazu brauchst du dann aber Invoking, Marshaling und lauter so Zeug, wo jeder .Net-Entwickler Angst hat davor.

Ich würde eher versuchen, das Fehlverhalten der Listview zu kompensieren.

neothemachine 1. Jun 2007 17:00

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Ok.... das mit dem kompensieren is leichter gesagt als getan ;) Noch jemand ne Idee?

s-off 1. Jun 2007 18:35

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hi,

im Usenet ist diese Frage x-Fach diskutiert worden; ob es eine Lösung gibt, ohne ListColumn.Width zu bemühen, kann ich Dir nicht sagen. Aber vielleicht bist Du ja noch gar nicht auf die Idee gekommen, da zu suchen :P

Vielleicht wäre auch noch eine Möglichkeit, bei einer Spalte mit 0-Breite auf das OnResize-Event oder so zu reagieren.

neothemachine 1. Jun 2007 18:39

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Zitat:

Zitat von s-off
im Usenet ist diese Frage x-Fach diskutiert worden; ob es eine Lösung gibt, ohne ListColumn.Width zu bemühen, kann ich Dir nicht sagen. Aber vielleicht bist Du ja noch gar nicht auf die Idee gekommen, da zu suchen :P

Hm, tatsache, da hab ich noch nich geguckt :lol:

Zitat:

Zitat von s-off
Vielleicht wäre auch noch eine Möglichkeit, bei einer Spalte mit 0-Breite auf das OnResize-Event oder so zu reagieren.

Daran hatte ich auch mal kurz gedacht, aber das funktioniert vermutlich nicht so wirklich gut, weil man ja dann die Spalte daneben u.U. nicht resizen kann.

neothemachine 1. Jun 2007 19:10

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Ok.... 100 Newsgroup Threads später... das was wohl am interessantesten ist:

Zitat:

Hi,

There is no easy workaround to achieve this. If you set the column Width to 0,
users can still resize the column using Mouse at runtime.
May be you can use DataGrid control and hide the column there.

317951 HOW TO: Hide a Column in a Windows Form DataGrid
http://support.microsoft.com/?id=317951

Hope this helps!
Bharat Patel
Microsoft, Visual Basic .NET
Man beachte, von wem es kommt ;)

90% haben das mit Width=0 geschrieben, die restlichen sagen man muss die ListView neu erstellen, was ich dann wohl machen werde.. Ich glaube mich dran zu erinnern, dass man irgendwie das Zeichnen eines Controls deaktivieren und wieder aktivieren kann, das geht vielleicht, um das Flackern zu verhindern, was beim neuerstellen der Liste kommen wird. Hm, hab ich nicht noch den Quellcode vom Taskmanager von Windows? Mal gucken wie MS das macht...:P

Falls jemanden noch was einfällt, solls ers sagen, ansonsten Danke fürs nachdenken ;) Vielleicht mach ich dann ne ListView Komponente draus..mal gucken

Maik

marabu 2. Jun 2007 15:09

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hallo Maik,

ich würde - vorzugsweise bei einer virtuellen ListView - einfach die Spalten entfernen und einfügen um deren Sichtbarkeit zu steuern.

Grüße vom marabu

neothemachine 3. Jun 2007 16:41

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
@marabu: ja das ist ja das Problem. Wenn man das macht, treten merkwürdige Effekte auf. Neue Daten werden dann in die falschen Spalten eingetragen.

Die einzige Möglichkeit das "sauber" zu machen, ist die Items zu clearen, die Spalten zu löschen und dann alles neu einzutragen. So machts auch MS, wie ich rausgefunden hab (Taskmanager). Ist auch nicht weiter schwer, allerdings wollte ich daraus eine neue ListView-Komponente machen, damit man nicht bei jeder ListView den Zusatz-Code (und das ist schon ne Menge) hinzufügen muss.

Neue Komponente TListViewHide....von TListView abgeleitet....noch nie gemacht, hab auch keine Ahnung wie. :-D Deswegen waren meine Versuche in den letzten Stunden auch etwas vergeblich. Ich will dem TListColumn (meine Ableitung: "TListColumnHide") eine neue Property namens "Visible" geben. Dazu muss ja aber mein TListViewHide auch die abgeleiteten Columns benutzen (auch abgeleitet zu: "TListColumnsHide", welche dann die TListColumnHide's benutzen soll), aber ich scheitere immer an den Zugriffsbeschränkungen, z.B.:

In ComCtrls steht ja:
Delphi-Quellcode:
constructor TCustomListView.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
{...}
  FListColumns := TListColumns.Create(Self);
{...}
end;
Das müsste ich ersetzen mit FListColumns := TListColumnsHide.Create(Self);

Was natürlich in der TListViewHide.Create nicht funktioniert, da FListColumns ja private ist.

Ich weiß wirklich nicht, wie ich da rangehen soll.. :|

Kann mich jemand in die richtige Richtung schieben? Oder treten? :P

Gremlin 3. Jun 2007 17:03

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Mach es wir @Marabu gemeint hat mit einer virtuellen Listview und erstelle dir für die Steuerung der Spalten eine vernünftige Verwaltungsstruktur.

Luckie 3. Jun 2007 17:10

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Grundidee: Trenne die Daten von der Darstellung. Halte die Daten in einer entsprechenden Datenstruktur vor. Wird eine Spalte ausgeblendet, fülle den Listview neu aus der Datenstruktur, ebendso, wenn die Spalte wieder eingeblendet wird.

neothemachine 3. Jun 2007 17:24

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
@Gremlin: Sagt mir, wenn ich mich irre, aber das dürfte auch nicht funktionieren. Das Problem ist ja, dass man (ob nun direkt einfügen, oder mit OnData) nach dem Löschen von Spalten nicht mehr auf die ID oder Index oder was auch immer der Spalte zugreifen kann, weil sie einfach nicht mehr der aktuellen Anordnung entspricht. Man kann sich das so vorstellen... Ich habe die Spalten "Name", "Nachname" und "Alter", füge mit Caption und SubItems die Daten "Max", "Muster" und "18" hinzu. Wenn ich dann mit .Free eine Spalte lösche und vielleicht noch die Spaltenanordnung, dann mache ich eine neue Zeile Caption="Max2", dann ändere ich die Spaltenanordnung, mache wieder eine neue Zeile Caption="Max3". Allerdings stehen nun Max2 und Max3 nicht in der selben Spalte, was sie aber tun, wenn man keine Spalten gelöscht hat. Ich behaupte jetzt einfach mal, dass es keinen anderen Weg gibt, als die ListView neu mit Daten (Spalten und Items) zu befüllen, damit alles stimmt.

Zitat:

Zitat von Luckie
Grundidee: Trenne die Daten von der Darstellung. Halte die Daten in einer entsprechenden Datenstruktur vor. Wird eine Spalte ausgeblendet, fülle den Listview neu aus der Datenstruktur, ebendso, wenn die Spalte wieder eingeblendet wird.

Genau das will ich machen. Die Daten sind sind schon in einer eigenen Datenstruktur. Ich weiß wie ichs machen müsste, aber ich will es direkt in die TListView kapseln als Komponente eben, die auch andere leicht verwenden können.

Luckie 3. Jun 2007 17:33

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Zitat:

Zitat von neothemachine
Genau das will ich machen. Die Daten sind sind schon in einer eigenen Datenstruktur. Ich weiß wie ichs machen müsste, aber ich will es direkt in die TListView kapseln als Komponente eben, die auch andere leicht verwenden können.

Und genau das würde ich nicht machen. Was wenn jemand eine andere Komponente benutzt? Dann kann er mit deiner Komponente auch nichts anfangen.

neothemachine 3. Jun 2007 17:38

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Zitat:

Zitat von Luckie
Und genau das würde ich nicht machen. Was wenn jemand eine andere Komponente benutzt? Dann kann er mit deiner Komponente auch nichts anfangen.

...Ist das nicht immer so? Es gibt einige ListView-Komponenten im Netz, wieso sollte ich da nicht auch eine machen? Ich mein, sind Komponenten nicht dazu da? Ich kann auch meinen Quellcode dann als Tutorial verbreiten, aber so wäre es doch für den Enduser viel leichter oder?

omata 3. Jun 2007 18:01

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hallo neothemachine,

mal davon abgesehen, dass ich es auch für sinnvoll halte die Daten und das Anzeigen zu trennen.

Hier mal ein Vorschlag der in deine Richtung geht...

Delphi-Quellcode:
type
  TMyListColumns = class(TListColumns)
  end;

  TMyListView = class(TListView)
  private
    FMyListColumns:TMyListColumns;
  public
    constructor create(Aowner:TComponent); reintroduce;
    destructor destroy; override;
  end;


{ TMyListView }

constructor TMyListView.create(Aowner: TComponent);
begin
  inherited create(Aowner);
  Self.Columns.free;
  FMyListColumns:=TMyListColumns.Create(Self);
  Self.Columns:=FMyListColumns;
end;

destructor TMyListView.destroy;
begin
  inherited;
end;
Gruss
Thorsten

neothemachine 3. Jun 2007 18:11

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Thorsten, viiiielen Dank, das sieht mal nach einer guten Idee aus, hätte ich auch drauf kommen können...mal sehen obs geht

Und glaub mir, ich bin auch für das Daten&Layout-Trennen Prinzip, aber ich bin noch kein Delphi-Profi, klappt also nicht immer so wies im Idealfall sein soll, aber ich arbeite dran. So nun geh ich mal an die Arbeit... :)

omata 3. Jun 2007 18:59

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hallo neothemachine,

ich habe mir das jetzt nochmal angesehen. Leider musste ich feststellen das das doch nicht so geht. Bei meinem ersten Test ging es wohl nur scheinbar.

Sorry,
Thorsten

neothemachine 3. Jun 2007 19:05

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Ja..ich komm auch nicht weiter, kommen immer Access Violations, wenn er Self.Columns:= FListColumnsHide; machen will. Man kann wohl Columns nicht einfach so ersetzen, schade eigentlich..

marabu 3. Jun 2007 22:16

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich bin nicht sicher, ob mein Beitrag #7 richtig verstanden wurde, deshalb habe ich hier eine kleine Demo angehängt. Sie soll nur den Lösungsansatz zeigen und verwendet eine CheckListBox um die Sichtbarkeit der Spalten zu steuern, deshalb: Bitte keine DoubleClicks auf die CheckListBox.

Gute Nacht

neothemachine 3. Jun 2007 23:04

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hm, interessant, ich versteh zwar noch nich den kompletten Code, aber das liegt an der Uhrzeit :P

Wenn ich bei der Demo beim ListView FullDrag=true mache, scheints nicht mehr richtig zu gehen, sobald man Spalten verschiebt. Woran könnte das liegen?

Danke für die Mühe! Super Arbeit!!

blablab 4. Jun 2007 00:42

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Mein Senf dazu:

Genau das gleiche Problem hatte ich auch mal. Und nach stundenlangem Ausprobieren bin ich dann zu dem ergebnis gekommen, dass die einzigste Lösung ist, jedesmal die ganze listview neu mit daten zu füllen. Da ich aber teilweise bis zu 1.000.000 Datensätze hatte, und das ganze sowieso etwas langsam war hab ich mich für DBGrid entschieden, was in meinem Fall wahrscheinlich auch die beste Entscheidung war. (Auch wenn ich bei DBGrid wieder einen Bug entdecken musste...)
Da das DBGrid bei dir so wies aussieht nicht in Frage kommt, wünsch ich dir noch viel Glück beim Umgehen des Problems... :thumb:

CCRDude 4. Jun 2007 07:24

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Wie groß ist denn dein Bildschirm?

Mit OwnerData (das ich schon ab mehreren Dutzend Einträgen einsetzen würde) bleibt gerade mal ein Neusetzen der paar angezeigten (OnData), und selbst hochkant dürften dann nicht mehr als 100 Einträge neu gelesen und gezeichnet werden müssen.

marabu 4. Jun 2007 07:53

Re: ListView Columns aus- und einblenden (nicht width=0!)
 
Hallo,

Zitat:

Zitat von neothemachine
... ich versteh zwar noch nich den kompletten Code ...

bevor du dir den Code nicht vollständig erschlossen hast, solltest du nicht versuchen die Komplexität zu erhöhen (FullDrag). Meine Demo zeigt nur, dass der von mir angedachte Weg funktionieren kann. Um alle Besonderheiten zu berücksichtigen werden wohl noch ein paar zusätzliche Zeilen Code nötig sein.

Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:35 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