2015-01-05 18 views
0

TTreeViewItem에서 모든 자식을 삭제하는 방법이 있습니까? DeleteChildren을 시도했지만 충돌이 발생합니다.TTreeViewItem에서 모든 하위 항목을 삭제하는 방법은 무엇입니까?

나는 단순한 질문이 더 많은 질문을 생성하는 것으로 밝혀졌습니다. 그래서 내가하는 일에 대해 설명합니다.

내 응용 프로그램은 Delphi XE5 FMX에서 디렉토리 트리를 생성하려고합니다. 나는 그것을 위해 TTreeView를 사용한다. TTreeView가 소유하고있는 TTreeViewItem의 모든 드라이브 목록을 생성하여 시작합니다. 사용자가 항목을 클릭하면 아래 디렉토리가 디렉토리에 추가되고 클릭시 펼쳐지는 TTreeViewItem이 추가됩니다. 사용자가 다시 클릭하면 TTreeViewItem이 호출됩니다. 하나의주의 사항이 있습니다 : 사용자가 다음 번에 같은 TTreeViewItem을 클릭하면 디렉토리 목록이 기존 목록에 추가됩니다 (아래 이미지 참조). 현재 목록을 지우고 싶습니다.

A list of duplicated directories

내가 다른 지점에 예외를 얻을 TTreeViewItem에서 TreeViewItem.DeleteChildren를 사용하여 아이를 삭제했을 때, 아래 그림을 참조하십시오.

Error message

는 몇 가지 질문에 관해서는 : 예, 나는 단지 TTreeViewItems를 추가 확신이 내가 OnClick 이벤트 (import_directory_click)을 할당하는 유일한 컨트롤입니다. 나는 완전한 코드를 추가하고 확신하기 위해 비 본질적인 것들을 주석 처리했다.

나는 누군가가이 기능이 이미 존재한다는 것을 알기를 원하지만 (심지어 찾지 못했을지라도) 나는 여전히 TTreeView를 관리하는 방법을 알고 싶어한다.

procedure TMain.import_initialize; 
    var 
    Item: TTreeViewItem; 
    drive: Char; 
    start: string; 
    begin 
    Directory_Tree.Clear; 

    {$IFDEF MSWINDOWS} 
    // When Windows, just present a list of all existing drives 
    for drive := 'C' to 'Z' do 
    begin 

    // A drive exists when its root directory exists 
     start := drive + ':\'; 
     if TDirectory.Exists (start) then import_add (start, Directory_Tree); 
    end; // for 
    {$ELSE} 
    // All other systems are unix systems, start with root. 

    drive := '/'; 
    start:= drive; 
    Item := import_add (TPath.GetPathRoot (start), DirectoryTree); 
    import_get_dirs (Item, start); 
    {$ENDIF} 
    start := TPath.GetSharedPicturesPath; 
    import_add (start, Directory_Tree); 
    if start <> TPath.GetPicturesPath 
     then import_add (TPath.GetPicturesPath, Directory_Tree); 
    // import_test_selection (''); 
    end; // import_initialize // 

    procedure TMain.import_directory_click (Sender: TObject); 
    var 
    TreeItem: TTreeViewItem; 
    obj: TFMXObject; 
    first_file: string; 
    begin 
    GridPanelLayout.Enabled := False; 
    if Sender <> nil then 
    begin 
     TreeItem := Sender as TTreeViewItem; 
     if TreeItem.IsExpanded then 
     begin 
      TreeItem.CollapseAll; 
     end else 
     begin 
      TreeItem.DeleteChildren; // <== this statement 
      import_get_dirs (TreeItem, TreeItem.Text); 
    { 
      first_file := find_first (TreeItem.Text, Selected_Images); 
      if first_file <> '' then 
      begin 
       Image.Bitmap.LoadFromFile (first_file); 
       GridPanelLayout.Enabled := True; 
      end; // if 
    } 
      TreeItem.Expand; // <== causes an exception over here 
     end; // if 
    end; // if 
    end; // import_directory_click // 

    procedure TMain.import_get_dirs (Start_Item: TTreeViewItem; start: string); 
    var 
    DirArray: TStringDynArray; 
    DirArraySize: Int32; 
    i: Int32; 
    begin 
    DirArray := TDirectory.GetDirectories (start); 
    DirArraySize := Length (DirArray); 
    for i := 0 to DirArraySize - 1 
     do import_add (DirArray [i], Start_Item); 
    end; // get_dirs // 

    function TMain.import_add (dir: string; owner: TControl): TTreeViewItem; 
    var 
    TreeItem: TTreeViewItem; 
    begin 
    TreeItem := TTreeViewItem.Create (owner); 
    TreeItem.text := dir; 
    TreeItem.OnClick := import_directory_click; 
    // TreeItem.Parent := owner; 
    owner.AddObject (TreeItem); 
    Result := TreeItem; 
    end; // import_add // 
+2

"원인이 충돌합니다."자세히 말씀해 주시겠습니까? –

+0

@Jerry, 당신 말이 맞아요. 질문의 업데이트를 참조하십시오. – Arnold

+5

TreeItem.Expand가 포함 된 모든 것을 삭제했다면 어떻게 될지 잘 모르겠다. 'DeleteChildren'은 모든 자식들을 삭제하고'Children'을 nil로 설정합니다. –

답변

2

TreeItem.DeleteChildren은 하위 항목 대신 항목 콘텐츠 사이트를 삭제하는 것으로 보입니다. 다음과 같이 사용하는 것이 좋습니다.

for i := TreeItem.Count - 1 downto 0 do 
    TreeItem.RemoveObject(TreeItem.Items[i]); 
+0

그게 다야! 나는 거의 비슷한 것을했다. 나는 아이들을 조작했다. 'TreeItem.Children.Count'와'TreeItem.Children.RemoveObject (i)' '그것은 아주 이상한 결과를 낳습니다.고마워요! 모든 것이 예상대로 작동합니다. – Arnold

관련 문제