1) Ativando o arrastar
procedure TForm1.GridOrigemCellClick(Column: TColumn);
begin
GridOrigem.BeginDrag(True);
end;
Ao chamar o método BeginDragM e passar o parâmetro como True, informamos ao DBGrid que é para iniciar a tarefa de arrastar. Você vai observar que ao clicar no registro, o ponteiro do mouse muda seu estado, indicando que a operação de arrastar está ativa.
Lembre-se que a operação é “arrastar e soltar”, portanto temos que ter um outro componente que vai receber os dados que estão sendo arrastados a partir do GridOrigem.
2) Preparando um TMemo para receber os dados
procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := Source is TDBGrid;
end;
O evento DragOver é disparado quando um objeto é arrastado sobre um controle, neste caso, sobre nosso TMemo1. Veja que o evento possui uma variável Accept que indica se o controle (TMemo1) deve aceitar ou não o objeto que vai ser “soltado” sobre ele.
É neste evento que decidimos de quem nosso TMemo1 pode receber informações. Após aceitar o objeto temos que implementar o evento que vai lidar, tratar, com os dados desse objeto.
3) Lidando com os dados que são “soltos”
procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
Memo1.Lines.Add((Source as TDBGrid).DataSource.DataSet.FieldByName('NOME').AsString);
end;
O evento DragDrop possui uma variável Source, que indica o objeto origem, e como nosso TMemo só recebe de TDBGrid, fazemos um TypeCast de TObject para TDBGrid. Podemos também arrastar e soltar entre TDBGrids. Vamos preparar nosso GridDestino.
1) Preparado o GridDestino
procedure TForm1.GridDestinoDragOver(Sender, Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean);
begin
Accept := (Sender is TDBGrid);
end;
Da mesma forma como o TMemo1, estamos determinando de quem o GridDestino pode receber informações.
2) Lidando com as informações do GridOrigem
procedure TForm1.GridDestinoDragDrop(Sender, Source: TObject; X,
Y: Integer);
var
Coordenadas: TGridCoord;
lNome: string;
begin
Coordenadas := THackGrid(GridDestino).MouseCoord(X,Y);
if (Coordenadas.X > 0) AND (Coordenadas.Y > 0) then
begin
lNome := cdsOrigemNome.AsString;
with THackGrid(GridDestino) do
begin
DataSource.DataSet.MoveBy(Coordenadas.Y - Row);
DataSource.DataSet.Insert;
Columns.Items[-1 + Coordenadas.X].Field.AsString := lNome;
end;
end;
end;
Agora pode parecer um pouco complicado, mas não é não. A classe TDBGrid possui algumas propriedades protegidas que podem ser muito úteis, mas como são protegidas não conseguimos acessá-las através da classe em si, porque não estão expostas. Mas podemos fazer um truque para acessá-las, esse truque é chamado de Hack. Para acessar a parte protegida (protected) de uma classe, criamos uma classe derivada dela, e fazemos um typecast no objeto que desejamos hackear. Na seção interface da unit, criamos uma classe que herda de TDBGrid.
THackGrid = class(TDBGrid);
É através dela que conseguimos acesso à parte protegida da classe TDBGrid e atribuímos à variável Coordenadas a posição do mouse em relação ao GridDestino.
De posse das coordenadas, verificamos se o mouse está sobre alguma linha do GridDestino, estando, movendo o Data para o registro em que o mouse está sobre, e damos um insert, dessa maneira o novo registro será inserido na posição do mouse.