2010-03-10 4 views
2

가끔씩 변경 될 수있는 수천 개의 항목을 표시하기 위해 VirtualTreeView를 사용합니다.이 경우 트리가 정리되어 다시 채워집니다.VirtualTreeview : 언제 아이들을 정렬합니까?

정렬은 자동으로 수행되지만 (toAutoSort 플래그가 설정 됨) 모든 노드를 반복적으로 초기화하는 원치 않는 효과가 있으며 이는 예상 한대로 매우 비싼 작업입니다.

따라서 toAutoSort이 꺼져있을 때 .Sort 방법으로 전화해야합니까? DoInitChildren은 그럴듯 해 보였지만 결과가 반대로 바뀌어 이상한 결과를 얻었으므로 아이들을 분류 할 좋은 이벤트가 없다고 가정합니다.)

답변

4

이 새로운 종류의 시나리오에서 일반적인 규칙은 모든 새 항목이 추가 된 후에 정렬하는 것입니다. 그렇게하면 한 번만 정렬 (및 초기화) 할 수 있습니다.

+0

"새로운"항목은 없습니다. 트리는 단순히 수정되고 재구성됩니다 (트리를 뒷받침하는 데이터 구조가 제 경우에 완전히 변경됨). –

+1

트리를 "재구성"하는 것은 새 트리를 만드는 것과 같습니다. 원칙은 동일합니다 : 정렬 일시 중지, 구성 시작, 모든 노드 추가, 구성 종료, 정렬. –

1

매번 전체 트리가 완전히 다른 경우가 아니라면 트리를 지우지 않고 항목 목록 (항목 식별)을 별도로 작성하고 목록을 정렬 한 다음 두 트리를 모두 보면서 성능을 향상시킬 수 있습니다 목록 정렬 상태를 유지

LeftCur := 0; 
RightCur := 0; 
while (LeftCur < TotalLeft) and (RightCur < TotalRight) then 
    begin 
    if LeftList[LeftCur] = RightList[RightCur] then 
     begin 
     // matches, so just advance 
     Inc(LeftCur); 
     Inc(RightCur);    
     end 
    else if LeftList[LeftCur] < RightList[RightCur] then 
     begin 
     // insert happens BEFORE RightCur 
     InsertLeftItemToRight; 
     Inc(RightCur); 
     Inc(TotalRight); 
     end 
    else if LeftList[LeftCur] > RightList[RightCur] then 
     begin 
     DeleteRightItem; 
     Dec(TotalRight); 
     end; 
    end; 
    While RightCur < TotalRight do 
    begin 
     DeleteRightItem; 
     Dec(TotalRight); 
    end; 
    While LeftCur < TotalLeft do 
    AppendLeftItemToRight; 

이 방법, 당신 : 위해 ... 일반적인 알고리즘은 이런 식으로 뭔가를 (왼쪽 목록은 "새 목록"이고 오른쪽 목록은 "기존 목록"입니다) 보이는 InsertLeftItemToRight 단계에서 항목로드 만 완료하면됩니다. 나무에서, 당신이 매치 할 때마다, 당신은 아이들을위한 비슷한 일과를 실행합니다. 이 개념은 기존 목록의 항목이 많이 변경되지 않거나 완전히로드되는 데 비용이 많이들 수 있다는 사실에 비중을 둡니다.

+0

상세한 답변을 보내 주셔서 감사하지만 VirtualTreeView는 매우 빠르고 단순한 Clear/Reload 전술로 충분합니다. (분명히 제외하고 제외하고 :) –

관련 문제