2016-04-19 7 views
-1

私は、ツリービューとリストビューと、ツリービューからリストビューに選択項目を移動するボタンを持っています。選択と転送は完璧に行われていますが、ツリービューからアイテムを削除することはできません。ツリービューの下で単一の項目を選択した場合にのみ機能します。 TreeView1.MultiSelect := Trueを持っているときに問題があります。ここでループ内のTreeViewからユーザーが選択したアイテムを削除するときに、無効なインデックスエラーを回避するにはどうすればよいですか?

は、私が使用していますコードです:

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 

上記のコードは、特定の選択後に無効なインデックスを提供します。完璧ではない場合があります。選択した2つのうち1つだけが追加されます。

が試み:

  1. For i := TreeView1.Items.Count to 1 do Begin
  2. 移入リストビューは、最初にして代わりにそれをやってsimulatainouslyの、ツリービューから削除しようとしました。同じエラー。
  3. 親と子を配列に格納した後、名前を付けて削除しようとしました。問題はツリービューで選択されていない特定の項目です。

これは私が最後の要素を選択すると、親ノード内のすべての要素が

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; 

答えて

5
のようにループのためにあなたを変更

コピーされ機能していないコードです:

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

新しいコードが表示された後に編集

あなたはd IDは、実際のエラーメッセージを表示しない、またそれが発生した行に、私はそれがこのラインのルートレベルにツリービュー項目の

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

であると仮定する。それらは親を持たず(IOW Item[itr].Parentnilです)、結果はAccess violationのエラーです。親にアクセスする前に、アイテムに親があることを確認する必要があります。

エラーが他の場合は、明示してください。 @MBoは理由が選択を削除中に変化することで、報告されているように


編集は、回避策

を追加しました。これを回避するには、次の回避策を使用します。

フォームにブール値フィールド(例:TreeView1_Deleting)を設定し、ツリービューにOnChangingイベントを宣言します。

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

OnChangingイベントの実装:あなたが選択したノードが

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; 

私が言ったことを覚えておいてください削除手順で

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

最後に、以前のParentプロパティにアクセスについてルートレベルのノードの

+0

ごめんなさい、そのDownto 0のみ、小さなタイプ –

+0

@siddharthtaunk注 'TreeView1.Items.Count-1'! –

+0

ツリー内の最後のアイテムを選択すると無効なインデックスエラーが発生します。そしてツリーの2つか3つ以上のアイテムと@Tom Noted –

2

私は、このコードは本当にブランチ全体またはすべてのツリー(最後の要素を選択した場合)(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; 

をそして、それは両方の選択されたノードのラベルを出力し、親は、ルートレベルまでのラベル - そう選択ジャンプは

回避策(私はツリービューのソースでその理由が表示されていない)削除中にレベルアップ:マーク選択したノードは、選択範囲を削除し、マークを削除します

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

なんて厄介なこと!これはバグでなければなりません。おそらくそれを報告しましたか? –

+0

@Tom Brunberg私は疑問 - それはデルファイかWindowsコントロールの動作ですか? – MBo

+0

はい、それは問題です。あなたのように、私はDelphiコードで(削除されたものだけをトレースした後で)まだ理由は見つけられませんでした。 –

関連する問題