Question:
How can I remove a tile item or a tile group after dragging it outside TileControl without animation?
Answer:
In the VCL 20.2.5 version, we modified our TileControl and added the public TdxTileControlDragDropCustomObject.ImmediateFinish property. This was made in the context of the following thread - T970821: Add an ability to finish drag-and-drop tile items or tile group without animation. The property allows you to finish a drag-and-drop operation without showing animation.
With the ImmediateFinish property, you can use the following way to remove a dragged tile item or a tile group without unnecessary animation after Item/Group deletion:
Delphiuses
cxGeometry;
type
TdxTileControlDragDropCustomObjectAccess = class(TdxTileControlDragDropCustomObject);
TdxTileControlDragDropItemAccess = class(TdxTileControlDragDropItem);
procedure <Form>.<AdxTileControl>MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FOriginalWndProc := TdxTileControl(Sender).WindowProc;
TdxTileControl(Sender).WindowProc := MyWindowProc;
end;
procedure <Form>.<AdxTileControl>MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOriginalWndProc) then
begin
TdxTileControl(Sender).WindowProc := FOriginalWndProc;
FOriginalWndProc := nil;
end;
end;
procedure <Form>.MyWindowProc(var AMessage: TMessage);
var
AUpMessage: TWMLButtonDown absolute AMessage;
ADragDropItem: TdxTileControlDragDropItem;
ADragDropGroup: TdxTileControlDragDropGroup;
AItems: TdxTileControlCheckedItems;
I: Integer;
ATileControl: TdxTileControl;
begin
ATileControl := <AdxTileControl>;
if (AMessage.Msg = WM_LBUTTONUP) and (ATileControl.DragAndDropState = ddsInProcess) then
begin
if (ATileControl.DragAndDropObject is TdxTileControlDragDropItem) and
not cxRectIntersect(TdxTileControlDragDropCustomObjectAccess(ATileControl.DragAndDropObject).DragBounds,
ATileControl.ClientBounds) then
begin
ADragDropItem := TdxTileControlDragDropItem(ATileControl.DragAndDropObject);
ADragDropItem.ImmediateFinish := True;
DoDeleteItem(ADragDropItem.DragItem);
AItems := TdxTileControlDragDropItemAccess(ADragDropItem).CheckedItems;
if AItems <> nil then
for I := 0 to AItems.Count - 1 do
DoDeleteItem(AItems[I]);
end
else
if (ATileControl.DragAndDropObject is TdxTileControlDragDropGroup) and
not cxRectIntersect(TdxTileControlDragDropCustomObjectAccess(ATileControl.DragAndDropObject).DragBounds,
ATileControl.ClientBounds) then
begin
ADragDropGroup := TdxTileControlDragDropGroup(ATileControl.DragAndDropObject);
ADragDropGroup.ImmediateFinish := True;
ADragDropGroup.DragGroup.Visible := False;
PostMessage(Handle, WM_DELETE_TILE_GROUP, TdxNativeUInt(ADragDropGroup.DragGroup), 0);
end;
end;
FOriginalWndProc(AMessage);
end;
procedure <Form>.DoDeleteItem(AItem: TdxTileControlItem);
begin
AItem.Visible := False;
PostMessage(Handle, WM_DELETE_TILE_ITEM, TdxNativeUInt(AItem), 0);
end;
procedure <Form>.WMDeleteTileItem(var AMessage: TMessage);
begin
<AdxTileControl>.DeleteItem(TdxTileControlItem(AMessage.WParam));
end;
procedure <Form>.WMDeleteTileGroup(var AMessage: TMessage);
var
AGroup: TdxTileControlGroup;
I: Integer;
ATileControl: TdxTileControl;
begin
ATileControl := <AdxTileControl>;
ATileControl.BeginUpdate;
try
AGroup := TdxTileControlGroup(AMessage.WParam);
for I := AGroup.ItemCount - 1 downto 0 do
ATileControl.DeleteItem(AGroup.Items[I]);
ATileControl.RemoveGroup(AGroup);
finally
ATileControl.EndUpdate;
end;
end;