2016-04-19 10 views
-1

Ich habe eine Treeview und eine Listview, und eine Schaltfläche, die ausgewählte Elemente aus der Treeview in die Listview verschieben sollte. Die Auswahl und die Übertragung sind vollkommen in Ordnung, aber das Löschen der Elemente aus der Baumansicht ist nicht möglich. Es funktioniert nur, wenn ich ein einzelnes Element unter der Baumansicht auswähle. Wenn ich TreeView1.MultiSelect := True habe, dann gibt es ein Problem. HierWie vermeide ich ungültige Indexfehler beim Entfernen von benutzerdefinierten Elementen aus einer TreeView in einer Schleife?

ist der Code, ich verwende:

For i := 0 to TreeView1.Items.Count-1 do Begin 
If TreeView1.Items[i].Selected then 
Begin 
Itm := ListView1.Items.add; 
..... 
TreeView1.Items[i].Delete 

Der obige Code gibt einen ungültigen Index nach einer bestimmten Auswahl. Nicht perfekt manchmal wird nur einer von zwei ausgewählt hinzugefügt.

Versuchte:

  1. For i := TreeView1.Items.Count to 1 do Begin
  2. Populated Listview und dann versuchte, von treeview zu löschen, statt simulatainously es zu tun. Derselbe Fehler.
  3. Versucht, Parent und Child in einem Array zu speichern und sie später mit dem Namen zu löschen. Problem ist ein bestimmter Artikel, der in der Baumansicht nicht ausgewählt ist.

Dies ist der Code, der nicht funktioniert, wenn ich wählen Sie das letzte Element alle Elemente in den übergeordneten Knoten

for Itr := TreeView1.Items.Count-1 downto 0 do Begin 
    if TreeView1.Items[Itr].Selected then 
    begin 
    Str := TreeView1.Items[Itr].Parent.Text + ' ,' + TreeView1.Items[Itr].Text; 
    TrimLeft(Str); 
    for k := 0 to SaveList.Count -1 do Begin 
     If ansipos(Str, SaveList[k]) > 0 Then Begin 
     Value := StringReplace(SaveList[k], Str, '',[rfReplaceAll, rfIgnoreCase]); 
     End; 
    End; 
    Itm := ListView1.Items.Add; 
    Itm.Caption := TreeView1.Items[Itr].Parent.Text; 
    Itm.SubItems.Add(TreeView1.Items[Itr].Text); 
    Itm.SubItems.Add(Value); 
    TreeView1.Items[Itr].Delete 
    end; 
End; 

Antwort

5
kopiert werden

Ihre Änderung für Schleife wie:

For i := TreeView1.Items.Count-1 downto 0 do 
.... 

Bearbeiten nach neuem Code dargestellt

Sie d id zeigen nicht die tatsächliche Fehlermeldung, noch auf welche Linie es passiert, aber ich nehme an, es auf dieser Linie ist

Str := TreeView1.Items[Itr].Parent.Text + ' ,' + TreeView1.Items[Itr].Text; 

für einen TreeView Artikel auf Root-Ebene. Diese haben kein Elternteil (IOW Item[itr].Parent ist nil) und das Ergebnis ist ein Access violation Fehler. Bevor Sie versuchen, auf das übergeordnete Element zuzugreifen, müssen Sie überprüfen, ob das Element übergeordnete Elemente aufweist.

Wenn Ihr Fehler etwas anderes ist, bitte klären.


bearbeiten, Abhilfe

hinzugefügt

Als @MBo berichtet, ist der Grund, dass die Auswahl Änderungen beim Löschen. Um dies zu verhindern, können Sie die folgende Problemumgehung verwenden.

Deklarieren Sie ein boolesches Feld, z. B. TreeView1_Deleting in Ihrem Formular und ein OnChanging Ereignis für die Strukturansicht.

type 
    TForm1 = class(TForm) 
    TreeView1: TTreeView; 
    Button1: TButton; 
    ... 
    procedure TreeView1Changing(Sender: TObject; Node: TTreeNode; 
     var AllowChange: Boolean); 
    private 
    TreeView1_Deleting: boolean; 
    end; 

und die Umsetzung der OnChanging Veranstaltung:

procedure TForm1.TreeView1Changing(Sender: TObject; Node: TTreeNode; 
    var AllowChange: Boolean); 
begin 
    if TreeView1_Deleting then 
    AllowChange := False; 
end; 

, schließlich in dem Verfahren, in dem Sie die ausgewählten Knoten

begin 
    TreeView1_Deleting := True; // Add this line 

    for i := TreeView1.Items.Count-1 downto 0 do 
    begin 
    if TreeView1.Items[i].Selected then 
    begin 
     // copy values to listview 
     // and finally delete the node 
     TreeView1.Items[i].Delete; 
    end; 
    end 

    TreeView1_Deleting := False; // Add this line 
end; 

löschen Denken Sie daran, was ich gesagt hat früher in Bezug auf die Parent Eigenschaft Zugriff eines Root-Level-Knotens.

+0

Es tut mir leid, seine Downto 0 nur, kleiner Tippfehler –

+0

@siddharthtaunk Beachten Sie auch 'TreeView1.Items.Count-1'! –

+0

Ich erhalte einen ungültigen Indexfehler, sobald ich das letzte Element in der Baumstruktur auswähle. Und mehr als zwei oder drei Elemente in der Struktur und @Tom Noted –

2

Ich kann bestätigen, dass dieser Code tatsächlich den ganzen Zweig löscht oder alle den Baum (wenn das letzte Element ausgewählt ist) (XE3, Win7/32):

for I := TreeView1.Items.Count - 1 downto 0 do begin 
    if TreeView1.Items[i].Selected then begin 
     Memo1.Lines.Add(TreeView1.Items[i].Text); 
     TreeView1.Items[i].Delete; 
    end; 
    end; 

Und es gibt sowohl ausgewähltes Knoten-Label und Eltern-Etiketten auf root-Ebene nach oben - so Auswahl Sprünge Stufe nach oben beim löschen (ich habe keinen Grund, in treeview Quellen sehen)

Umgehung: Markierung ausgewählten Knoten, die Auswahl entfernen, löschen markiert:

var 
    i: Integer; 
    Node: TTreeNode; 
begin 
    for I := TreeView1.SelectionCount - 1 downto 0 do begin 
     Node := TreeView1.Selections[i]; 
     Memo1.Lines.Add(Node.Text); 
     Node.Data := Pointer(-1); 
    end; 
    TreeView1.Selected := nil; 
    for I := TreeView1.Items.Count - 1 downto 0 do 
    if TreeView1.Items[i].Data = Pointer(-1) then 
     TreeView1.Items[i].Delete; 
+0

Was für eine böse Sache! Dies muss ein Fehler sein. Hast du es vielleicht gemeldet? –

+0

@Tom Brunberg Ich bezweifle - ist es Delphi oder Windows-Steuerelement Verhalten – MBo

+0

Ja, das ist die Frage. Wie Sie, habe ich noch keinen Grund gefunden (nachdem ich nur einen durch die Löschung verfolgt habe) in Delphi-Code. –

Verwandte Themen