unir listbox arrastando

02/12/2005

1

Pessoal, minha dúvida é a seguinte: tenho 2 listbox e uma stringgrid.

eu queria arrastar um item da listbox da direita para dentro da listbox da esquerda, grudando-o (ou selecionando) um item desta da esquerda. Ao unir os dois itens, ambos vão para a stringgrid.

Ou, uma outra opção seria arrastar os itens direto pra stringgrid.

Se possível, gostaria que string do item aparecesse ou fosse visível enquanto arrastasse. Nunca fiz nada nesse sentido de arrastar e soltar, por isso preciso de ajuda.


Obrigado a todos! ^^


Responder

Posts

02/12/2005

Rgaffo

Boa tarde,

Não sei bem como fazer, só sei que para fazer esse recurso vc tem que usar Drag and Drop, pesquise sobre isso.
Se vc observar os objetos tem o evento OnDraDrop (Ao arrastar e soltar).

Falow.


Responder

02/12/2005

Marco Salles

So para dar um pontape inicial.. Outras maneiras irão surgir.
Bem eu não entendi o que voce queis dizer com [b:37e2ed41e7]grudando-o (ou selecionando)[/b:37e2ed41e7] mas se o problema inicial for arrastar e soltar aqui vai um exemplo com dois list Box

1)[b:37e2ed41e7] propriedade do DragMode dos ListBox em dmAutomatic[/b:37e2ed41e7]

2) coloque a titulo de experimento o codigo abaixo;

var
i:Integer;


{$R *.DFM}

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
var
texto:String;
begin
   accept:=false;
   texto:=ListBox2.items.strings[i];
   if listbox1.Items.IndexOf(texto) < 0  Then
     accept:=true;
end;


procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
var
texto:String;
begin
accept:=false;
texto:=ListBox1.items.strings[i];
if listbox2.Items.IndexOf(texto) < 0  Then
accept:=true;
end;


procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
i:=ListBox2.ItemIndex;
ListBox1.Items.Add(ListBox2.items.strings[i]);
ListBox2.Items.Delete(i);
end;


procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
var
i:Integer;
begin
i:=ListBox1.ItemIndex;
ListBox2.Items.Add(ListBox1.items.strings[i]);
ListBox1.Items.Delete(i);
end;


procedure TForm1.ListBox2Click(Sender: TObject);
begin
i:=ListBox2.ItemIndex;
if i >= 0 Then
begin
  ListBox2.onDragOver:=nil;
  ListBox1.OnDragOver:=ListBox1DragOver;
end;
end;


procedure TForm1.ListBox1Click(Sender: TObject);
begin
i:=ListBox1.ItemIndex;
if i >= 0 Then
begin
  ListBox1.onDragOver:=nil;
  ListBox2.OnDragOver:=ListBox2DragOver;
end;
end;



Responder

02/12/2005

Vitor Rubio

o que eu quis dizer foi o seguinte: quando eu arrastar o item da listbox1 pra listbox2, o item não vai para a listbox2, nem precisa ser deletado da listbox1.
Quando eu ´Encostar´ o item arrastado da listbox1 em algum item da lisbox2, ambos, tanto o que eu arrastei quanto o que foi ´tocado´ por ele vão para um stringgrid.

é possivel fazer isso?


Responder

02/12/2005

Marco Salles

o que eu quis dizer foi o seguinte: quando eu arrastar o item da listbox1 pra listbox2, o item não vai para a listbox2, nem precisa ser deletado da listbox1.


isto não altera a idéia que tentei passar ...é so alterar o código de inserção e iliminação

Vamos supor que o ao inves de um edit voce que colocar o conteudo em um edit.. Para o caso de um StringList voce faz uma adaptação

Basta isso:

var
i:integer;

{$R *.DFM}

procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  edit1.text:=ListBox1.Items.Strings[i];
end;


procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
i:=ListBox1.ItemIndex;
if i >= 0 Then
   accept:=True
else
  accept:=False;
end;


Agora apara a segunda situação:
[b:679a433f98]Quando eu ´Encostar´ o item arrastado da listbox1 em algum item da lisbox2, [/b:679a433f98]

encostar sera complicado , porque o conteudo do listBox acredito que não
é gráfico...
:idea: :idea: :idea:
Mas voce pode mandar para o StringList todo o conteudo do ListBox2 que estiver selecionado , juntamente com o conteudo do listBpox1 que fora arrastado para o ListBox2 , Basta fazer uma pequena modificação:

procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
edit1.text:=ListBox1.Items.Strings[i];
if ListBox2.ItemIndex >=0 Then
edit1.Text:=Edit1.text+ ListBox2.Items.Strings[ListBox2.ItemIndex] ;
end;



Responder

02/12/2005

Vitor Rubio

eu entendi. Mas será que da pra fazer isso então: quando eu arrastar um item da lista1 pra lista2, automaticamente será selecionado o item da lista2 que estiver debaixo do ponteiro do mouse?

se eu conseguir fazer isso, aí eu estarei com um item selecionado em cada lista, e ao soltar o botão do mouse, ambos serão deletados e incluidos na minha stringgrid assim:

campo |valor
(item arrastado da lista1)|(item debaixo do mouse na lista2)
.... |.....

Isso enriqueceria bastante uma interface com o usuário, pois ficaria igual a algumas telas do access, por exemplo, onde é só arrastar e soltar um valor de um campo pra outro. (na tela de relacionamentos por exemplo, onde vc une duas chaves de tabelas diferentes arrastando o nome da chave).


piconclado, né?


Responder

03/12/2005

Marco Salles

fiz esta rotina para fonte.size do ListBox2 maior ou igual a 8
resolução 800X600 pixels , monitor de 17...
É so uma idéia inicial , talvez lhe sirva em função de sua necessidade..
Por exemplo um tamanho fixo de elementos no ListBox, sem a barra de rolagem ,
No mais apos entender o que se passa talvez ea para adaptar a sua necessidade

implementation

var
i:integer;

{$R *.DFM}


procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
i:=ListBox1.ItemIndex;
if i >= 0 Then
   accept:=True
else
  accept:=False;
end;


procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
edit1.text:=ListBox1.Items.Strings[i];
if ListBox2.ItemIndex >=0 Then
edit1.Text:=Edit1.text+ ListBox2.Items.Strings[ListBox2.ItemIndex] ; 
end;



******[b:4320ffbc93]este evento esta relacionado com o ListBox1[/b:4320ffbc93]
procedure TForm1.ListBox1EndDrag(Sender, Target: TObject; X, Y: Integer);
var
 fonte:integer;
 correcao:integer;
begin
fonte:=ListBox2.Font.Size;
correcao:=fonte+8;
y:=y div (correcao);
if y <= ListBox2.Items.Count-1 then
  edit1.text:=edit1.text+ListBox2.Items.Strings[y];
end;


testei com varias fontes do listbox e aparentemente os resultados forama satisfatorios.. A maior dificuldade no entanto e achar a melhor relação entre o Y do evento ListBox1EndDrag , que esta como inteiro , para o numero de pixels que cada fonte ocupa dentro do ListBox


Responder

15/12/2005

Marco Salles

é ja vi que voce não gostou :cry: :cry: ... Nao respondeu nada :cry:
Achou meio gambiarra né :lol: .. Mas podia ter opinado. :evil:
:D :D Mas sou insistente e sempre durmo com o problema

:idea: :idea:
[b:5607cfdfb8]Segue sem a gambiarra :[/b:5607cfdfb8]

var
i:integer;
arrastou:boolean;


procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
 i:=ListBox1.ItemIndex;
if i >= 0 Then
   accept:=True
else
  accept:=False;
end;


procedure TForm1.ListBox2MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var pt:TPoint;
begin
if arrastou then
begin
  pt.X := X;
  pt.Y := Y;
  ListBox2.ItemIndex := ListBox2.ItemAtPos(pt, true);
  if ListBox2.ItemIndex >= 0 Then
  edit1.text:=ListBox1.Items.Strings[i]+ListBox2.Items[ListBox2.ItemIndex]
  else
   edit1.text:=ListBox1.Items.Strings[i]+ListBox2.Items[listbox2.Items.Count-1];
  arrastou:=False;
 end;
end;


procedure TForm1.ListBox1EndDrag(Sender, Target: TObject; X, Y: Integer);
begin
arrastou:=True;
end;


[b:5607cfdfb8]Acho que desta vez foi né [/b:5607cfdfb8] :?: :?: :?: :?:


Responder