« ☆TListを使ったリスト No3 | トップページ | ☆ListViewの背景に画像を描画する。 »

☆ListViewのDrag&Drop

ViewStyleがvsReportに設定されたListViewのDrag&Dropの処理です。
ListViewは、Ctrl+左クリックで飛び飛び選択?Shift+左クリックで範囲選択?を行えますね。
ということで次の2点を考慮した処理にしたいと思います。

1.複数選択されたアイテムを扱える。
2.他のListViewへのDrag&Dropができる。(同じアイテムを表示している場合)
  ※自アプリ内に限ります。他アプリではOLE Drag&Drop処理が必要です。

通常DropTargetがnilの場合には、処理させないことが多いんじゃないかと思います。しかし今回は、他のListViewへのDrag&Dropも考慮するので、nilの場合には最後に追加する形で処理させたいと思います。

ListView1DragOver、ListView1DragDropは、ListView1、ListView2共に設定しておいて下さい。

procedure MakeSampleData(ListView: TListView);
var
  Column: TListColumn;
  ListItem: TListItem;
  I: Integer;
  S,S1,S2,S3: String;
begin
  ListView.ViewStyle := vsReport;

  // Columnの設定
  for I := 0 to 2 do
  begin
    Column := ListView.Columns.Add;
    case I of
      0: S := 'name';
      1: S := 'address';
      2: S := 'telephone';
    end;
    Column.Caption := S;
    Column.Width := 100;
  end;

  // ListItemの設定
  for I := 0 to 6 do
  begin
    ListItem := ListView.Items.Add;
    case I of
      0: begin
          S1 := '(1) hiderin';
          S2 := 'kyoto';
          S3 := '075-xxx-xxxx';
         end;
      1: begin
          S1 := '(2) yuki';
          S2 := 'tokyo';
          S3 := '03-xxxx-xxxx';
         end;
      2: begin
          S1 := '(3) picasso';
          S2 := 'barcelona';
          S3 := '932-xxx-xxx';
         end;
      3: begin
          S1 := '(4) momo';
          S2 := 'kobe';
          S3 := '078-xxx-xxxx';
         end;
      4: begin
          S1 := '(5) john';
          S2 := 'newyork';
          S3 := '212-xxx-xxxx';
         end;
      5: begin
          S1 := '(6) taro';
          S2 := 'fukuoka';
          S3 := '092-xxx-xxxx';
         end;
      6: begin
          S1 := '(7) jun';
          S2 := 'sapporo';
          S3 := '011-xxx-xxxx';
         end;
    end;

    ListItem.Caption := S1;
    ListItem.SubItems.Add(S2);
    ListItem.SubItems.Add(S3);
  end;
  ListView.DragMode := dmAutomatic;
  ListView.MultiSelect := True;
  
  // ドラッグ中のイメージをさせない---なんか中途半端で嫌なので(^^;
  ListView.ControlStyle := ListView.ControlStyle - [csDisplayDragImage];
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
  // アイテムを作成します。
  MakeSampleData(ListView1);
  MakeSampleData(ListView2);
end;

procedure TForm1.ListView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := True;
end;

procedure TForm1.ListView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  I: Integer;
begin
  for I := 0 to (Source as TListView).SelCount -1 do
  begin
    if ((Sender as TListView).DropTarget = nil) then
      // 追加
      (Sender as TListView).Items.Add.Assign((Source as TListView).Selected)
    else
      // 挿入
      (Sender as TListView).Items.Insert(
        (Sender as TListView).DropTarget.Index).Assign(
        (Source as TListView).Selected);

    (Source as TListView).Selected.Delete;
  end;
end;


Drag&Drop時に隠れているアイテムをスクロール表示させるには、TreeViewで行った方法がそのまま使えます。 ぜひ実装してより実用的なものにして下さい。

参考
☆TreeViewのDrag&Drop

|

« ☆TListを使ったリスト No3 | トップページ | ☆ListViewの背景に画像を描画する。 »