2011-12-13 30 views
5

Tôi có một danh sách các nút. Tôi muốn thêm một tính năng kéo-và-thả-để-sắp xếp lại, nhưng tôi không biết làm thế nào để đi về việc này.Kéo và thả VirtualTreeview để sắp xếp các nút trong danh sách

Tôi đã thử sử dụng sự kiện OnDragDrop của TVirtualStringTree, nhưng tôi không thể tìm ra. Tôi nhìn vào tài liệu và có thật đáng buồn là không có mã mẫu tối thiểu ở đó cho kéo thả nút đồng bằng.

Xin lưu ý rằng đây chỉ là danh sách cấp một. Không hierachy. :)

+0

Nó phụ thuộc vào cách bạn đã xây dựng cây của bạn. Cung cấp thêm thông tin về điều đó. – Linas

+0

Mọi thứ được lưu trữ trong Dữ liệu của PVirtualNode, nếu đó là ý của bạn? Nó giống như một listview thực sự. – Jeff

Trả lời

11

Nếu bạn đang nhận dữ liệu thông qua GetNodeData hơn kéo và thả của bạn có thể được thực hiện như thế này:

uses 
    ActiveX; 

Gán sự kiện kéo đến cây:

OnDragAllowed:

procedure TForm1.vt1DragAllowed(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; 
    var Allowed: Boolean); 
begin 
    Allowed := True; 
end; 

OnDragOver:

procedure TForm1.vt1DragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; 
    State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean); 
begin 
    Accept := (Source = Sender); 
end; 

OnDragDrop:

procedure TForm1.vt1DragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; 
    Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); 
var 
    pSource, pTarget: PVirtualNode; 
    attMode: TVTNodeAttachMode; 
begin 
    pSource := TVirtualStringTree(Source).FocusedNode; 
    pTarget := Sender.DropTargetNode; 

    case Mode of 
    dmNowhere: attMode := amNoWhere; 
    dmAbove: attMode := amInsertBefore; 
    dmOnNode, dmBelow: attMode := amInsertAfter; 
    end; 

    Sender.MoveTo(pSource, pTarget, attMode, False); 

end; 

Cũng đừng quên đặt toAutoDeleteMoveNodes False trong TreeOptions.AutoOptions.

+0

Cảm ơn! Hoạt động hoàn hảo! :) – Jeff

+0

Bất kỳ ý tưởng nào về cách di chuyển nhiều nút (trong một danh sách cấp một)? Tôi đã thử lấy tất cả các nút đã chọn - không chỉ là 'FocusedNode' - nhưng với rất ít thành công. Mặc dù SelectedCount lớn hơn 1 và 'GetFirstSelected' trả về' FocusedNode', 'GetNextSelected' trả về nil. – DarkByte

+0

@Linas - làm thế nào bạn có được điều này để làm việc cùng với mã svTrees của bạn? Khi sử dụng giải pháp này với giải pháp bạn đã đăng trong "Cơ sở hạ tầng giống cây (để sử dụng với VirtualTreeview)", nó dường như chỉ cập nhật VSTree chứ không phải cấu trúc dữ liệu cơ bản – TheSteven

0

Nhiều nút drag'n'drop:

procedure TForm1.vst(Sender: TBaseVirtualTree; 
    Source: TObject; DataObject: IDataObject; Formats: TFormatArray; 
    Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode); 
var 
    pSource, pTarget: PVirtualNode; 
    attMode: TVTNodeAttachMode; 
    List: TList<PVirtualNode>; 
begin 
    pTarget := Sender.DropTargetNode; 

    case Sender.GetNodeLevel(pTarget) of 
    0: 
     case Mode of 
     dmNowhere: 
      attMode := amNoWhere; 
     else 
      attMode := amAddChildLast; 
     end; 
    1: 
     case Mode of 
     dmNowhere: 
      attMode := amNoWhere; 
     dmAbove: 
      attMode := amInsertBefore; 
     dmOnNode, dmBelow: 
      attMode := amInsertAfter; 
     end; 

    end; 
    List:= TList<PVirtualNode>.create(); 
    pSource := Sender.GetFirstSelected(); 
    while Assigned(pSource) do 
    begin 
    List.Add(pSource); 
    pSource := Sender.GetNextSelected(pSource); 
    end; 

    for pSource in List do 
    Sender.MoveTo(pSource, pTarget, attMode, False); 

List.Free; 
end; 
Các vấn đề liên quan