![]() |
Kaban |
Índice
Introdução
Nesse post iremos ver um exemplo de uso dos eventos de Drag and Drop (arrasta e solta) do Delphi. Drag and Drop - Kaban - em Delphi. Esse exemplo poderá ser utilizado para criar um quadro tipo Kanban, que pode ser utilizado para organizar a fazeres do dia a dia ou do trabalho.
Explorando a Propriedade DragMode e os Eventos OnDragDrop e OnDragOver no Delphi
O Delphi é uma ferramenta poderosa para o desenvolvimento de aplicações ricas e interativas, e um dos recursos mais úteis para criar interfaces dinâmicas é o suporte a drag-and-drop. Este recurso permite que os usuários arrastem objetos ou dados de uma parte da aplicação para outra, oferecendo maior interatividade e flexibilidade. Neste artigo, vamos explorar como usar a propriedade DragMode e os eventos OnDragDrop e OnDragOver no Delphi.
Entendendo a Propriedade DragMode
No Delphi, a propriedade DragMode é usada em conjunto com o mecanismo de arrastar e soltar. Ela define o comportamento do componente ao receber um item durante a operação de drag-and-drop. Normalmente, você configurará a propriedade DragMode de um componente para dmAutomatic ou dmManual, o que determina se ele responderá automaticamente ou exigirá intervenção do desenvolvedor.
- dmAutomatic: O componente entra automaticamente no modo de arrastar quando o usuário inicia uma operação de drag-and-drop.
- dmManual: Exige que você inicie explicitamente a operação usando o método
BeginDrag
.
Evento OnDragOver
O evento OnDragOver é acionado continuamente enquanto o usuário arrasta um item sobre o componente. Ele é usado para validar se o destino aceita ou não o item que está sendo arrastado.
Estrutura do Evento
procedure(Sender: TObject; Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean) of object;
- Sender: O componente que está recebendo o evento.
- Source: O componente que iniciou a operação de arrastar.
- X, Y: Coordenadas do ponteiro do mouse no momento.
- State: O estado atual do arraste (dsDragEnter, dsDragLeave, dsDragMove).
- Accept: Um valor booleano que indica se o componente aceita o item arrastado.
Exemplo de Uso
No exemplo abaixo, o componente destino aceita apenas objetos arrastados de um componente específico:
procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := Source is TButton; // Aceita apenas botões
end;
Evento OnDragDrop
O evento OnDragDrop é acionado quando o usuário solta o objeto arrastado sobre o componente. Aqui você implementa a lógica para manipular o item que foi arrastado e definir como ele será tratado.
Estrutura do Evento
procedure(Sender: TObject; Source: TObject; X, Y: Integer) of object;
- Sender: O componente que está recebendo o evento.
- Source: O componente que iniciou o arraste.
- X, Y: Coordenadas do mouse no momento em que o item é solto.
Exemplo de Uso
No exemplo abaixo, um botão é movido para um novo painel quando solto:
procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if Source is TButton then
begin
TButton(Source).Parent := TPanel(Sender); // Move o botão para o novo painel
TButton(Source).Left := X;
TButton(Source).Top := Y;
end;
end;
Passo a Passo: Implementando Drag-and-Drop no Delphi
No exemplo abaixo iremos demonstrar como mover painéis de um lado para o outro, como se fosse um Kanban.
- Arraste 5 painéis(TPanel) para o form principal. Três painéis serão utilizados como containers e dois painéis serão utilizados como tarefas.
- Configuração do Componente de Origem:
- Defina a propriedade DragMode como dmAutomatic.
- Adicione eventos de suporte, como
OnMouseDown
para iniciar o arraste se estiver usando dmManual.
3. Configuração do Componente de Destino:
- Adicione o evento OnDragOver para validar se o objeto pode ser solto.
- Adicione o evento OnDragDrop para manipular a lógica de soltar o item.
4. Implementação no Código: Configure os eventos no código ou no Object Inspector.
Código Completo
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
pnlToDo: TPanel;
pnlTask1: TPanel;
pnlTask2: TPanel;
pnlInProgress: TPanel;
pnlDone: TPanel;
procedure FormCreate(Sender: TObject);
procedure panelContainerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
procedure panelContainerDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure panelTaskDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
private
FDraggingPanel: TPanel;
procedure InitializeKanban;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeKanban;
end;
procedure TForm1.InitializeKanban;
begin
// Configuração inicial dos painéis que servirão de containers
pnlToDo.Caption := 'To Do';
pnlInProgress.Caption := 'In Progress';
pnlDone.Caption := 'Done';
// Configuração inicial dos painéis de tarefas
pnlTask1.Caption := 'Task 1';
pnlTask2.Caption := 'Task 2';
//Configurar os painéis para o modo de arrasto automático
pnlTask1.DragMode := TDragMode.dmAutomatic;
pnlTask2.DragMode := TDragMode.dmAutomatic;
pnlToDo.DragMode := TDragMode.dmAutomatic;
pnlInProgress.DragMode := TDragMode.dmAutomatic;
pnlDone.DragMode := TDragMode.dmAutomatic;
//Configurar os eventos de arrastar sobre dos painéis
pnlTask1.OnDragOver := panelTaskDragOver;
pnlTask2.OnDragOver := panelTaskDragOver;
pnlToDo.OnDragOver := panelContainerDragOver;
pnlInProgress.OnDragOver := panelContainerDragOver;
pnlDone.OnDragOver := panelContainerDragOver;
//Configurar os eventos de arrastar e soltar dos painéis
pnlToDo.OnDragDrop := panelContainerDragDrop;
pnlInProgress.OnDragDrop := panelContainerDragDrop;
pnlDone.OnDragDrop := panelContainerDragDrop;
end;
procedure TForm1.panelContainerDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
FDraggingPanel.Align := alBottom; //configura o painel para se alinhar no fundo - essa configuração fará com que as tarefas fiquem ordenadas uma embaixo da outra, ao arrastar
FDraggingPanel.Parent := TPanel(Sender); //configura o novo pai do painel tarefa
FDraggingPanel.Align := alTop; //configura o painel para se alinhar ao topo - essa configuração fará com que as tarefas fiquem ordenadas uma embaixo da outra, ao arrastar
FDraggingPanel := nil //Limpa a variável que recebe o painel que representa a tarefa.
end;
procedure TForm1.panelContainerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := (Sender is TPanel); //Configura os painéis que serão os containers para aceitar outros painéis
end;
procedure TForm1.panelTaskDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
if Sender is TPanel then
begin
FDraggingPanel := TPanel(Sender); //Seta a variável FDraggingPanel para receber o painel que representa a tarefa.
end;
end;
end.
Para ver o funcionamento basta clicar em cima dos painéis "Task 1" ou "Task 2" e arrastar e soltar para os painéis "To Do", "In Progress" ou "Done".
Veja abaixo a ilustração do projeto:
![]() |
Ilustração do Projeto. |
Código fonte do exemplo
Você pode fazer o download do exemplo do projeto através do repositório do github:
https://github.com/Gisele-de-Melo/Drag-and-Drop
Dicas Práticas
- Validação no OnDragOver: Use o parâmetro
Accept
para evitar comportamentos inesperados, validando os componentes que podem ser arrastados. - Organização Visual: Ao soltar o item, ajuste sua posição para evitar sobreposição ou desalinhamento.
- Customização: Combine drag-and-drop com efeitos visuais, como mudanças na cor do componente destino ao aceitar um objeto.
Conclusão
Os eventos OnDragOver e OnDragDrop oferecem uma base poderosa para implementar interatividade no Delphi, permitindo criar interfaces intuitivas e dinâmicas. Seja para construir um Kanban, um editor visual ou qualquer aplicação que requeira movimentação de componentes, o suporte a drag-and-drop no Delphi é uma solução elegante e eficaz.
Com essas dicas e exemplos, você está pronto para explorar ainda mais o potencial dessa funcionalidade e criar aplicações ricas em funcionalidades para seus usuários.
Nenhum comentário:
Postar um comentário