单行选中的时候,很容易就可以实现移动了。如果是多行选中(用Shift和Ctrl键多选),有什么好的算法可以使选中的行都上移或下移?

解决方案 »

  1.   

    笨法是缓存选中项,然后用for循环移动
      

  2.   

    TFormDemo = class(TForm)
        ListView: TListView;
        ButtonDown: TButton;
        ButtonUp: TButton;
        procedure ButtonDownClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure ButtonUpClick(Sender: TObject);
      private
        OldListViewWindowProc: TWndMethod;
        procedure NewListViewWindowProc(var Message: TMessage);
      public
        { Public declarations }
      end;var
      FormDemo: TFormDemo;implementation{$R *.dfm}procedure ExchangeItems(lv: TListView; const i, j: Integer);
    var
      tempLI: TListItem;
    begin
      lv.Items.BeginUpdate;
      try
        tempLI := TListItem.Create(lv.Items);
        tempLI.Assign(lv.Items.Item[i]);
        lv.Items.Item[i].Assign(lv.Items.Item[j]);
        lv.Items.Item[j].Assign(tempLI);
        tempLI.Free;
      finally
        lv.Items.EndUpdate
      end;
    end;procedure MoveUp(LV: TListView);
    var
      Idx: Integer;
    begin
      if LV.SelCount > 0 then
      begin
        if not LV.Items[0].Selected then
        begin
          for Idx := 1 to Pred(LV.Items.Count) do
          begin
            if LV.Items[Idx].Selected then
            begin
              ExchangeItems(LV, Idx, Idx-1);
              LV.Items[Idx].Selected := False;
              LV.Items[Idx -1].Selected := True;
            end;
          end;
        end;
      end;
    end;procedure MoveDown(LV: TListView);
    var
      Idx: Integer;
    begin
      if LV.SelCount > 0 then
      begin
        if not LV.Items[Pred(LV.Items.Count)].Selected then
        begin
          for Idx := Pred(LV.Items.Count) downto  1 do
          begin
            if LV.Items[Idx-1].Selected then
            begin
              ExchangeItems(LV, Idx -1, Idx);
              LV.Items[Idx -1].Selected := False;
              LV.Items[Idx].Selected := True;
            end;
          end;
        end;
      end;
    end;procedure TFormDemo.NewListViewWindowProc(var Message: TMessage);
    begin
      if Message.Msg = WM_KillFocus then
        Exit;
      OldListViewWindowProc(Message);
    end;procedure TFormDemo.FormCreate(Sender: TObject);
    begin
      OldListViewWindowProc := ListView.WindowProc;
      ListView.WindowProc := NewListViewWindowProc;
    end;----------测试procedure TFormDemo.ButtonDownClick(Sender: TObject);
    begin
      MoveDown(ListView);
    end;procedure TFormDemo.ButtonUpClick(Sender: TObject);
    begin
      MoveUp(ListView);
    end;