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. ich
ll have a look at this but i don't think i can use it because the project is quite large and changing one of it
s 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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Rufen Sie die
UpdateItems
- Methode, nachdem Sie habe angeordnet, die Spalten. E. g.:Update:
In meinen tests, die ich noch zu benötigen scheint, die oben genannten call-in manchen Anlass. Aber das eigentliche problem ist, dass "es ist ein Fehler in der Delphi list-view-control".
Duplizieren das problem mit einem einfachen Projekt:
TListView
Kontrolle auf ein VCL-Formular, legen IhreViewStyle
zu 'vsReport', und legenFullDrag
auf 'true'.OnCreate
Ereignishandler des Formulars:TButton
auf dem Formular, und legen Sie die folgenden code, um seineOnClick
handler:Beachten Sie, dass 'Zelle 2' zurückerobert hat seine ursprüngliche position.
Fehler:
Den Spalten einer
TListView
(TListColumn
) hält seine Bestelldaten in seinerFOrderTag
Feld. Wenn Sie die Reihenfolge in einer Spalte (entweder durch Einstellung derIndex
Eigenschaft oder durch ziehen der header), dieseFOrderTag
wird entsprechend aktualisiert.Nun, wenn Sie eine Spalte hinzufügen, die
TListColumns
Sammlung, die Sammlung erstmals wird die neueTListColumn
und ruft dann dieUpdateCols
Methode. Das unten ist der code derUpdateCols
Methode derTListColumns
in D2007 VCL:Der obige code entfernt alle Spalten aus der zugrunde liegenden API-list-view-control und dann fügt Sie neu. Beachten Sie, wie der code weist jedem eingefügten Spalte
FOrderTag
index Zähler:Dies ist die Reihenfolge der Spalten von Links nach rechts an diesem Punkt in der Zeit. Wenn die Methode wird aufgerufen, wenn die Spalten sortiert sind anders als bei der Bildung der Zeit, dann, dass die Bestellung verloren gegangen ist. Und da sich die Gegenstände nicht ändern, Ihre Positionen entsprechend, alles Durcheinander.
Update:
Den unten Veränderung auf die Methode schien zu funktionieren, so wenig wie ich getestet habe, benötigen Sie zur Durchführung von mehr tests (offenbar diese Korrektur nicht in allen Fällen möglich, siehe 'torno' s Kommentare unten für details):
Wenn Sie nicht mit Paketen Sie können eine geänderte Kopie von 'comctrls.pas' zu Ihrem Projekt-Ordner. Sonst könnte man verfolgen, run-time-code-patching oder einen bug-report erstellen und warten für ein Update.
s a nice point. I
ll versuchen zu überprüfen, zu beheben und, wenn erfolgreich, ich werde berichten des Fehlers.ll see, that the order of the subitems for new items somehow still is messed up. e.g. just add a column to existing 3, move it to index 1, add a new item with subitems. the subitem[0] still has the wrong index "subitems.count-1" instead of 0. i think it may be, because the updatecols is just called after adding the column, not after overwriting it
s index. ich werde versuchen, wenn das einfügen der Spalte funktioniert.m using delphi xe and with delphi xe2 it also appeared, so it doesn't seem to be fixed. i
ll Bericht, aber leider, ich brauche eine Korrektur, die kompatibel zu delphi 7 und höher... :/ danke für Eure Hilfe.s at the end. sorry for confusing you. so i maybe don't have to save the indices for each item but for each column. that may be possible. thanks for indicating this. i
ll versuchen, eine Lösung zu finden und wenn Sie erfolgreich sind, schließe ich diesen Beitrag. vielen Dank nochmal 🙂