TListView: VCL verliert die Reihenfolge von Spalten wenn Sie eine Spalte hinzufügen

Ich versuche, fügen Sie eine Spalte zwischen zwei vorhandenen Spalten in eine TListView. Deshalb füge ich die neue Spalte am Ende, und verschieben Sie es, indem Sie es der index auf den gewünschten Wert. Das funktioniert, bis das hinzufügen eines weiteren neuen Spalte.

Was ich gemacht habe:
Fügen Sie die Spalte an Letzte position (Spalten.Hinzufügen) und fügen Sie dort den Unterpunkt auf der letzten position (Unterpositionen.Hinzufügen) zu. Danach habe ich bewegen Sie die Spalte, indem Sie ihn als index auf die richtige position.
Dies funktioniert gut, solange es nur eine Spalte, die Hinzugefügt wird. Beim hinzufügen einer zweiten Spalte, der Unterpunkte erhalten geschraubt. Die neue Unterposition der ersten Spalte bewegt wird, um die Letzte position, z.B. wie folgt:

0        |  1          |  new A       |  new B      | 3
Caption  |  old sub 1  |  old sub 3   |  new Sub B  | new sub A

Ich würde mich sehr freuen, wenn jemand helfen könnte!

Zum Beispiel, gibt es vielleicht ein Befehl oder eine Nachricht, die ich senden kann, um das ListView-Steuerelement, so dass es aktualisiert oder speichert es die Spalte --> dort den Unterpunkt Zuordnung, die ich verwenden könnte, nach dem hinzufügen des ersten neuen Spalte und es Unterpunkte, so kann ich mit dem zweiten neuen Spalte die gleiche Weise wie die erste.

Oder ist das nur ein bug von TListViews Spalte-->dort den Unterpunkt Handhabung oder TListColumns...?

Beispiel-code für ein vcl-Formulare-Anwendung (zuweisen der Form1.OnCreate-Ereignis):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    listview: TListView;
    initButton: TButton;
    addColumn: TButton;
    editColumn: TEdit;
    subItemCount: Integer;
    procedure OnInitClick(Sender: TObject);
    procedure OnAddClick(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  listview := TListView.Create(self);
  with listview do
  begin
    Left := 8;
    Top := 8;
    Width := self.Width - 30;
    Height := self.Height - 100;
    Anchors := [akLeft, akTop, akRight, akBottom];
    TabOrder := 0;
    ViewStyle := vsReport;
    Parent := self;
  end;

initButton := TButton.Create(self);
with initButton do
  begin
    left := 8;
    top := listview.Top + listview.Height + 20;
    Width := 75;
    Height := 25;
    TabOrder := 1;
    Caption := 'init';
    OnClick := OnInitClick;
    Parent := self;
  end;

  editColumn := TEdit.Create(self);
  with editColumn do
  begin
    left := initButton.Left + initButton.Width + 30;
    top := listview.Top + listview.Height + 20;
    Width := 120;
    Height := 25;
    TabOrder := 2;
    Parent := self;
    Caption := '';
  end;

  addColumn := TButton.Create(self);
  with addColumn do
  begin
    left := editColumn.Left + editColumn.Width + 10;
    top := listview.Top + listview.Height + 20;
    Width := 75;
    Height := 25;
    TabOrder := 1;
    Enabled := true;
    Caption := 'add';
    OnClick := OnAddClick;
    Parent := self;
  end;

end;

procedure TForm1.OnInitClick(Sender: TObject);
var col: TListColumn;
i, j: integer;
item: TListItem;
begin
  listview.Items.Clear;
  listview.Columns.Clear;

  // add items
  for I := 0 to 2 do
  begin
    col := ListView.Columns.Add;
    col.Caption := 'column ' + IntToStr(i);
    col.Width := 80;
  end;

  // add columns
  for I := 0 to 3 do
  begin
    item := ListView.Items.Add;
    item.Caption := 'ItemCaption';

    // add subitems for each column
    for j := 0 to 1 do
    begin
      item.SubItems.Add('subitem ' + IntToStr(j+1));
    end;
  end;

  subItemCount := 5;
end;

procedure TForm1.OnAddClick(Sender: TObject);
var number: integer;
col: TListColumn;
i: Integer;
ascii: char;
begin
  listview.Columns.BeginUpdate;

  number := StrToInt(editColumn.Text);
  ascii :=  Chr(65 + number);

  // create the new column
  col := TListColumn(ListView.Columns.add());
  col.Width := 80;
  col.Caption := ascii;

  // add the new subitems
  for I := 0 to ListView.Items.Count-1 do
  begin
    ListView.Items[i].SubItems.Add('subitem ' + ascii);
  end;

  // move it to the designated position
  col.Index := number;

  listview.Columns.EndUpdate;

  Inc(subItemCount);
end;

end.

Danke!


Bearbeiten: Die vorgeschlagenen fix von Sertac Akyuz funktioniert gut, aber ich kann es nicht verwenden, da sich der Delphi-Quellcode ist keine Lösung für mein Projekt. Bug ist gemeldet.

Bearbeiten: Entfernt die zweite Frage war das unbeabsichtigte enthalten in den ersten Beitrag und eröffnet neue Frage (Siehe verlinkten Frage und Frage-revision).

Update: Die gemeldete Fehler ist jetzt geschlossen, so festgelegt ist, wie von Delphi XE2 Update 4.

  • Ich denke, es gibt eine fehlende Aktualisierung/update irgendwo. Nicht sicher, was es ist obwohl. Das heißt, dies klingt wie ein weiterer Fall, in dem virtuellen Modus Listen-Ansichten glänzen würde.
  • Aber Sie sind nur für .Netz, sind Sie nicht? ich hab das gleiche problem mit gleicher C#.Net Projekt und vielleicht können es verwenden, gibt es.
  • Nein. Windows Listenansicht unterstützt virtual mode und Delphi wickelt es sehr schön. Wenn Sie das manipulieren von Spalten zur Laufzeit, es ist definitiv der Weg zu gehen. Jeder andere hier würde der Punkt, den Sie an der virtuellen Baum-Ansicht, aber ich mag die native Steuerung selbst.
  • ok, vielen Dank. ichll have a look at this but i don't think i can use it because the project is quite large and changing one of its Kern-Komponenten möglicherweise nicht die beste Idee 🙂
  • Hatte einen Blick durch den VCL-code und es scheint, dass irgendwo entlang der Linie, die Aktualisierung den index einer Spalte, die VCL-Daten bekommt out of sync mit dem windows-listview-Daten, bei denen die Unterelemente betroffen sind. Um das Spiel mit Begin/EndUpdate hat eine Wirkung leider bisher noch nicht die gewünschte. Ihre beste Wette kann ja sein, setzen die ListView im virtuellen Modus, da @David vorgeschlagen. Damit ist Ihre app ist immer gefragt, für die Daten die es braucht, um zu zeigen, in jeder Zelle, und es gibt keine versteckten "kopieren" in der vcl oder windows.
  • Es klingt wie Sie sollte aufhören, die Liste Anzeigen und verwenden zu einem realen Netz.
  • danke für die Vorschläge, aber mit den virtuellen Modus oder ein Gitter ist keine option.

InformationsquelleAutor torno | 2011-11-24
Schreibe einen Kommentar