如何更改ListView OnDrag图像?

时间:2013-07-31 23:28:15

标签: delphi listview drag delphi-xe4

我正在使用带ViewStyle的ListView:= vsReport。当我从一个点拖动一行到另一个点时,它会拖动被拖动的行的第一列的值(在它是1的情况下)并将其显示在深灰色矩形内,如下所示。

enter image description here

我试过在XE4源代码中查找但无法找到此背景颜色的设置位置。我想将此背景颜色更改为clSkyBlue(或类似的东西),但不知道它是如何完成的。

如何更改拖动操作的默认深灰色背景图像?

1 个答案:

答案 0 :(得分:2)

VCL的拖动操作没有开箱即用的拖动图像,但它确实提供了一种提供要使用的拖动图像的机制。这通常通过构建您自己的"拖动图像列表"来完成,或者通过覆盖控件本身的GetDragImages方法(当使用内部拖动对象时),或者通过构建自己的" 34;拖动对象"当拖动开始时,并在其GetDragImages方法中组装图像列表,以便在启动拖动时由VCL调用。

对于TListViewTTreeView控件,此机制略有不同,因为底层api控件本身支持为被拖动的项提供拖动图像。因此,与其他控件不同,这些控件会覆盖其GetDragImages方法,并返回在覆盖DoStartDrag方法中创建的图像列表,其中控件要求api提供图像列表。这就是为什么你无法找到在VCL代码中创建拖动图像的原因。

要覆盖此行为,可能会在子类中覆盖这些(可能还有一些其他)方法并实现它们。我不知道这是否容易,我发现通过在OnStartDrag事件处理程序中构建拖动对象更容易提供图像列表。这通常没有任何影响,因为在调用我们的拖动对象的时间GetDragImages时,VCL已经确定了api提供的图像列表,并且api创建了一个临时列表。被拖了。然后,我们可以强制拖动原始图像列表并替换我们自己的。

下面是一个简单的例子。除了错误处理,资源保护,热点确定等等。查看VCL代码,看看它是如何确保实际上是一个被拖动的项目。

type
  TListWiewDragControlObjectEx = class(TDragControlObjectEx)
  protected
    function GetDragImages: TDragImageList; override;
  end;

function TListWiewDragControlObjectEx.GetDragImages: TDragImageList;
var
  Bmp: TBitmap;
  R: TRect;
begin
  Bmp := TBitmap.Create;
  Bmp.Canvas.Brush.Color := clSkyBlue;
  R := TListView(Control).Selected.DisplayRect(drBounds);
  Bmp.SetSize(R.Right - R.Left, R.Bottom - R.Top);
  Bmp.Canvas.Font := TListView(Control).Font;
  Bmp.Canvas.TextOut(0, 0, TListView(Control).Selected.Caption);

  Result := TDragImageList.Create(Control);
  Result.Width := Bmp.Width;
  Result.Height := Bmp.Height;
  ImageList_EndDrag;             // end the drag with the temporary list
  Result.SetDragImage(Result.Add(Bmp, nil), 0, 0);
  Bmp.Free;
end;

procedure TForm1.ListView1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
  DragObject := TListWiewDragControlObjectEx.Create(ListView1);
  DragObject.AlwaysShowDragImages := True;
end;