如何更改ListView OnDrag图像? [英] How to change the ListView OnDrag image?

查看:67
本文介绍了如何更改ListView OnDrag图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将ListView与ViewStyle:= vsReport一起使用.当我将一行从一个点拖到另一点时,它将获取要拖动的行的第一列的值(在这种情况下为1),并将其显示在深灰色矩形内,如下所示.

I'm using a ListView with the ViewStyle := vsReport. When I drag a row from one point to another point it takes the value of column one of the row being dragged (in the case it's 1) and displays it inside a dark grey rectangle as shown below.

我尝试在XE4源代码中四处查看,但是找不到设置此背景色的位置.我想将此背景颜色更改为clSkyBlue(或类似的颜色),但不知道它是如何完成的.

I've tried looking around in the XE4 source code but can't find where this background color is set. I'd like to change this background color to clSkyBlue (or something similar) but don't know how it's done.

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

How do you go about changing the default dark grey background image of the drag operation?

推荐答案

VCL的拖动操作没有开箱即用的拖动图像,但确实提供了一种提供要使用的拖动图像的机制.通常,通过覆盖控件本身的 GetDragImages 方法(使用内部拖动对象时)或构建自己的拖动对象"来构造自己的拖动图像列表"启动拖动后,在其 GetDragImages 方法中组合一个图像列表,以在拖动开始时由VCL调用.

VCL's drag operations does not have drag images out of the box, but it does provide a mechanism for providing a drag image to be used. This is normally done by constructing your own "drag image list", either by overriding the GetDragImages method of the control itself (when an internal drag object is used), or by constructing your own "drag object" when the drag is started, and assemble an image list in its GetDragImages method to be called by the VCL when the drag is initiated.

尽管对于 TListView TTreeView 控件,此机制有点不同,因为基础api控件本身本身就支持为要拖动的项目提供拖动图像.因此,与其他控件不同,这些控件将覆盖其 GetDragImages 方法,并返回在覆盖的 DoStartDrag 方法中创建的图像列表,其中控件要求api提供图像列表.这就是为什么您将找不到在VCL代码中创建拖动图像的位置的原因.

This mechanism is a bit different though for TListView and TTreeView controls because the underlying api controls themselves natively support providing a drag image for the item that's being dragged. Hence, unlike other controls, these controls override their GetDragImages methods and return the image list that's being created in overriden DoStartDrag methods where the controls ask the api to provide the image list. This is why you won't be able to find where a drag image is created in VCL code.

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

To override this behavior, one could possibly override these (and possibly a few other) methods in a descendant class and implement them. I don't know if this would be easy or not, I find providing an image list through constructing a drag object in the OnStartDrag event handler easier. This normally does not have any effect, since by the time GetDragImages of our drag object is called, the VCL already has settled on an image list which the api has supplied and the api has created a temporary list that's being dragged. Then, we can force the dragging of the original image list to an end and substitute our own.

下面是一个过于简化的示例.除了错误处理,资源保护,热点确定等以外,还可以查看VCL代码以了解它如何确保确实有一个被拖动的项目.

Below is an oversimplified example. Apart from error handling, resource protecting, hot spot determining etc.. look to VCL code to see how it ensures there's actually an item that's being dragged.

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;

这篇关于如何更改ListView OnDrag图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆