Dúvida com um ListBox... Coisa Simples.

Delphi

13/06/2006

Pessoal.

Gostaria de Resolver esse seguinte problema:

Tenho 2 Listbox, ambos sao alimentados quando o form e criado, um com X opçoes de um usuário Y logado no sistema, e o segundo listbox está com as opçoes disposiveis pra esse usuário Y, caso ele queira colocar mais opçoes para ele mesmo.

Simples: Gostaria que no primeiro listbox, nao tivessem as opçoes que o mesmo ja escolheu, ou seja, que ja estao no segundo listbox (quando escolho uma opcao, ela e movida do primeiro listbox pro segundo, eu disse MOVIDA :D )

É coisa simples, eu sei.. mas tipo, to esquentando o cocao com isso.

Podem me ajudar ?


Technos

Technos

Curtidas 0

Respostas

Vinicius2k

Vinicius2k

13/06/2006

Colega,

Algo como?
[URL=http://img159.imageshack.us/my.php?image=listbox7mf.png][img:5b2ba2e8ed]http://img159.imageshack.us/img159/1457/listbox7mf.th.png[/img:5b2ba2e8ed][/URL]

Você pode fazer +/- assim:
...
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  for I := 1 to 20 do
    ListBox1.Items.Add(´Opção ´ + Format(´¬3.3d´, [I]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Botão ">"
  if not (ListBox1.ItemIndex = -1) then
  begin
    ListBox2.Items.Add(ListBox1.Items[ListBox1.ItemIndex]);
    ListBox1.DeleteSelected;
  end;
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
  // Mesmo efeito do click no botão ">" para o duplo click
  // no ítem do 1º ListBox. Isto pode ser feito no object
  // inspector, mas está no código para exemplificar.
  Button1Click(Self);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // Botão "<"
  if not (ListBox2.ItemIndex = -1) then
  begin
    ListBox1.Items.Add(ListBox2.Items[ListBox2.ItemIndex]);
    ListBox2.DeleteSelected;
  end;
end;

procedure TForm1.ListBox2DblClick(Sender: TObject);
begin
  // Mesmo efeito do click no botão "<" para o duplo click
  // no ítem do 2º ListBox. Isto pode ser feito no object
  // inspector, mas está no código para exemplificar.
  Button2Click(Self);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  // Botão ">>"
  while ListBox1.Items.Count > 0 do
  begin
    ListBox1.ItemIndex := 0;
    ListBox2.Items.Add(ListBox1.Items[ListBox1.ItemIndex]);
    ListBox1.DeleteSelected;
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  // Botão "<<"
  while ListBox2.Items.Count > 0 do
  begin
    ListBox2.ItemIndex := 0;
    ListBox1.Items.Add(ListBox2.Items[ListBox2.ItemIndex]);
    ListBox2.DeleteSelected;
  end;
end;


Ainda dá para ´brincar´ um pouco mais, como permitir multi-seleção nos TListBox, por exemplo. Daí em diante segue-se a sua criatividade. Já me diverti um pouco fazendo isso. :)


GOSTEI 0
Technos

Technos

13/06/2006

Já Resolvi o problema.

Não dessa forma, mas de outra que eu mesmo bolei.

Mas de toda forma, valeu.

Só que pintou mais uma questão:

Tem como eu, assim que arrastar e soltar um item de um listbox, ele automaticamente arrastar e soltar os itens de um listbox que está oculto na janela ?

Isso pq tem um listbox visivel, que vc pode arrastar e soltar (ordenar da maneira que voce quiser) sem problema nenhum, mas tenho um que e uma especie de copia dele, que fica oculto (esse oculto tem os fieldnames de um dataset qualquer... o visivel armazena o displayname), onde eu posso organizar da maneira que eu em querer.

Tem como me ajudar nessa tb?


GOSTEI 0
Adriano Santos

Adriano Santos

13/06/2006

Já Resolvi o problema. Não dessa forma, mas de outra que eu mesmo bolei. Mas de toda forma, valeu. Só que pintou mais uma questão: Tem como eu, assim que arrastar e soltar um item de um listbox, ele automaticamente arrastar e soltar os itens de um listbox que está oculto na janela ? Isso pq tem um listbox visivel, que vc pode arrastar e soltar (ordenar da maneira que voce quiser) sem problema nenhum, mas tenho um que e uma especie de copia dele, que fica oculto (esse oculto tem os fieldnames de um dataset qualquer... o visivel armazena o displayname), onde eu posso organizar da maneira que eu em querer. Tem como me ajudar nessa tb?


[b:aea1c45899]Vinicius[/b:aea1c45899], posso me intrometer e melhorar seu algoritimo? :wink:

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Botão ">"
  if not (ListBox1.ItemIndex = -1) then
  begin
    ListBox2.Items.Add(ListBox1.Items[ListBox1.ItemIndex]);
    ListBox1.DeleteSelected;
  end;
end; 


Fica mais simples assim:
[quote:aea1c45899=´Adriano Santos´]
procedure TForm1.Button2Click(Sender: TObject);
begin
  //Já fica um mais simples e o ListBox se vira pra fazer o resto.
  ListBox1.MoveSelection(ListBox2);
end;

[/quote:aea1c45899]


Para o caso do [b:aea1c45899]´Move´[/b:aea1c45899] com o mouse, fiz um exemplo basicão.
Veja os eventos. Fica bem loko assim:

[quote:aea1c45899=´onEndDrag do ListBox1´]
procedure TForm1.ListBox1EndDrag(Sender, Target: TObject; X, Y: Integer);
begin
  if Target <> nil then
    // trata o fim de uma operacao que foi aceita
    ListBox1.MoveSelection(ListBox2);
end;

[/quote:aea1c45899]

[quote:aea1c45899=´onMouseDown do ListBox1´]
procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if (Sender = ListBox1) and (Button = mbLeft) then
    ListBox1.BeginDrag(False); // inicia a operacao
end;

[/quote:aea1c45899]


[quote:aea1c45899=´onDragDrop do ListBox2´]
procedure TForm1.ListBox2DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  if Source = ListBox1 then
    ListBox1.EndDrag(True); // comanda o final da operacao
end;

[/quote:aea1c45899]

[quote:aea1c45899=´onDragOver do ListBox2´]
procedure TForm1.ListBox2DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  if Source = ListBox1 then
    Accept := True; // aceita se vier da lista
end;

[/quote:aea1c45899]


GOSTEI 0
Vinicius2k

Vinicius2k

13/06/2006

[quote:ecb3728668=´Adriano Santos´][b:ecb3728668]Vinicius[/b:ecb3728668], posso me intrometer e melhorar seu algoritimo? :wink: [/quote:ecb3728668]
Sem problemas! Não liga não... vez por outra eu reinvento a roda :)
Se ligar o Multi-Select do TListBox, os botões ´>>´ e ´<<´ também podem receber apenas estes códigos, respecitvamente:
ListBox1.SelectAll;
  ListBox1.MoveSelection(ListBox2);

ListBox2.SelectAll;
  ListBox2.MoveSelection(ListBox1);


Eu não conhecia o método MoveSelection e, apenas a título de curiosidade, ele faz, basicamente o que eu havia proposto, porém de forma melhorada:

// Implemenação do método MoveSelection de TCustomListControl
procedure TCustomListControl.MoveSelection(
  Destination: TCustomListControl);
begin
  CopySelection(Destination);
  DeleteSelected;
end;


// Implementação do método CopySelection de TCustomListBox
procedure TCustomListBox.CopySelection(Destination: TCustomListControl);
var
  I: Integer;
begin
  if MultiSelect then
  begin
    for I := 0 to Items.Count - 1 do
      if Selected[I] then
        Destination.AddItem(PChar(Items[I]), Items.Objects[I]);
  end
  else
    if ItemIndex <> -1 then
      Destination.AddItem(PChar(Items[ItemIndex]), Items.Objects[ItemIndex]);
end;


Implementei aqui, naquele exemplo e em ambos os TListBox, o que você propôs e ficou legal! ;)


GOSTEI 0
Adriano Santos

Adriano Santos

13/06/2006

É isso ai Vinicius, uma mão lava a outra... :wink:


GOSTEI 0
POSTAR