我正在使用带ViewStyle的ListView:= vsReport。当我从一个点拖动一行到另一个点时,它会拖动被拖动的行的第一列的值(在它是1的情况下)并将其显示在深灰色矩形内,如下所示。
我试过在XE4源代码中查找但无法找到此背景颜色的设置位置。我想将此背景颜色更改为clSkyBlue(或类似的东西),但不知道它是如何完成的。
如何更改拖动操作的默认深灰色背景图像?
答案 0 :(得分:2)
VCL的拖动操作没有开箱即用的拖动图像,但它确实提供了一种提供要使用的拖动图像的机制。这通常通过构建您自己的"拖动图像列表"来完成,或者通过覆盖控件本身的GetDragImages
方法(当使用内部拖动对象时),或者通过构建自己的" 34;拖动对象"当拖动开始时,并在其GetDragImages
方法中组装图像列表,以便在启动拖动时由VCL调用。
对于TListView
和TTreeView
控件,此机制略有不同,因为底层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;