Avatar billede anold Nybegynder
29. november 2000 - 13:37 Der er 15 kommentarer og
2 løsninger

Drag og drop

Jeg har en listbox med en masse navne i, de navne vil jeg gerne kunne trække over i nogle nye listboxe\'e som jeg har oprettet dynamisk.
Hvordan gør jeg det
Avatar billede borrisholt Novice
29. november 2000 - 13:52 #1
Jeg har et eksempel med Listviews  stedet prøv der ...

Lav et nyt project og implemter unit1 sådan her :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure ListViewDragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);
    procedure ListViewDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure ListViewKeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
  private
    _ListView : TListView;
    __ListView : TListView;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  ListColumn : TListColumn;
  ListItem : TListItem;
  i : Integer;
begin
  _ListView := TListView.Create(form1);
  __ListView := TListView.Create(form1);

  with _ListView do
  begin
    Align := alLeft;
    ViewStyle := vsReport;
    RowSelect := true;
    ReadOnly :=true;
    FullDrag := true;
    OnDragOver := ListViewDragOver;
    OnDragDrop := ListViewDragDrop;
    OnMouseDown := ListViewMouseDown;
    OnKeyDown := ListViewKeyDown;
  end;

  with __ListView do
  begin
    Align := alClient;
    ViewStyle := vsReport;
    RowSelect := true;
    ReadOnly :=true;
    FullDrag := true;
    OnDragOver := ListViewDragOver;
    OnDragDrop := ListViewDragDrop;
    OnMouseDown := ListViewMouseDown;
    OnKeyDown := ListViewKeyDown;
  end;


  InsertControl(_ListView);
  InsertControl(__ListView);

  randomize;

  for i:= 0 to 3 do
  begin
    ListColumn := _ListView.Columns.Add;
    ListColumn.Caption := IntToStr(Random(5000));
    ListColumn.Alignment := taCenter;
    ListColumn.AutoSize :=TRUE;
  end;

  __ListView.Columns.Assign(_ListView.Columns);

  for i:= 0 to 15 do
  begin
    ListItem := _ListView.Items.Add;
    ListItem.Caption :=  IntToStr(Random(5000));
    ListItem.SubItems.Add(IntToStr(Random(5000)));
    ListItem.SubItems.Add(IntToStr(Random(5000)));
    ListItem.SubItems.Add(IntToStr(Random(5000)));
  end;
end;

procedure TForm1.ListViewDragOver(Sender, Source: TObject; X, Y: Integer;  State: TDragState; var Accept: Boolean);
begin
  Accept := Source is TListView;
end;

procedure TForm1.ListViewDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  ListItem : TListItem;
  DragPos : Integer;
begin
  DragPos :=(Sender as TListView).Items.IndexOf((Sender as TListView).GetItemAt(X,Y));

  if DragPos = -1 then
    DragPos := (Sender as TListView).Items.Count;

  ListItem  := (Source as TListView).Selected;
  (Sender as TListView).Items.Insert(DragPos);
  (Sender as TListView).Items[DragPos].Assign(ListItem);
  (Source as TListView).Items.Delete((Source as TListView).Items.IndexOf((Source as TListView).Selected));
end;


procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);
var
  DragItem: Integer;
begin
  if Button = mbLeft then
  begin
    DragItem := (Sender as TListView).Items.IndexOf((Sender as TListView).GetItemAt(X,Y));

    if (DragItem > -1) and (DragItem < (Sender as TListView).Items.Count) then
      (Sender as TListView).BeginDrag(False);
  end;
end;

procedure TForm1.ListViewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  i : Integer;
begin
  if key <> 39 then
    exit;
  if not Boolean(__ListView.Items.Count) then
    exit;
  i := _ListView.Items.IndexOf(_ListView.Selected);

  if i> __ListView.Items.Count-1 then
    i := __ListView.Items.Count-1;

  __ListView.Selected := __ListView.Items[i];
  __ListView.ItemFocused := __ListView.Selected;
  __ListView.SetFocus;
end;

end.

Jens B
Avatar billede anold Nybegynder
30. november 2000 - 09:47 #2
Hej Jens B

UHA hvor ser dit program fint ud...
Men ser du, jeg fatter ikke så meget af hvad der sker i programmet så kunne du omskrive det så det passer lidt mere til mit spørgsmål ???
Avatar billede delphi Nybegynder
30. november 2000 - 14:27 #3
Hvad med det her?

Som du kan se, så er der på formen en listbox (indeholdende nogle linier) samt en button.  Knappen benyttes til at oprette en dynamisk listbox.

unit fmMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TMainForm = class(TForm)
    FastListBox: TListBox;
    buCreateListbox: TButton;
    procedure ListBoxDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure ListBoxDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure buCreateListboxClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}


procedure TMainForm.FormCreate(Sender: TObject);
begin
  Height := 410;
  Width  := 720;
  FastListBox.MultiSelect := True;        // Tillad drag af mere end et navn.
  FastListBox.DragMode    := dmAutomatic;  // Enable dragging from listbox.
end;


procedure TMainForm.buCreateListboxClick(Sender: TObject);
begin
  // Opret en dynamisk Listbox.
  With TlistBox.Create(Self) Do
    Begin
      Parent := Self;
      Top    := 32;
      Left  := 224;
      Height := 273;
      Width  := 121;


      OnDragDrop := ListBoxDragDrop;
      OnDragOver := ListBoxDragOver;
    End;
end;

procedure TMainForm.ListBoxDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := Source Is TListBox;
end;

procedure TMainForm.ListBoxDragDrop(Sender, Source: TObject; X,
  Y: Integer);
Var
  lbReceiver : TListBox;
  lbSource  : TListBox;
  Index      : Integer;
  aStr      : String;
begin
  lbReceiver := Sender As TListBox;  // Listbox der droppes på.
  lbSource  := Source As TListbox;  // Listbox der dragges fra.

  For Index := 0 To lbSource.Items.Count-1 Do
    If lbSource.Selected[Index] Then
      Begin
        aStr := lbSource.Items[Index];
        lbReceiver.Items.Add(aStr);
      End;
end;

end.
Avatar billede anold Nybegynder
01. december 2000 - 07:46 #4
Hej Delphi (eller hedder det godmorgen)

Dit EKS. ser rigtig godt ud, det gør lige det jeg ønsker Men

1. Kan det ikke laves sådan at man ikke kan \'droppe\' navnet i den samme listbox som man drag\'er fra .

2. Når man har \'droppet\' et navn hvordan fjerne man det så fra den listbox man drag\'er fra


Avatar billede delphi Nybegynder
01. december 2000 - 09:26 #5
Den hurtigste løsning:  Lav DragOver metoden lidt om:

procedure TMainForm.ListBoxDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := (Source Is TListBox) And (Sender<>Source);
//  Accept := Source Is TListBox;
end;


Delphi
Avatar billede delphi Nybegynder
01. december 2000 - 09:27 #6
PS: I dag er det Peter\'s fødselsdag, hurra hurra hurra....
Avatar billede borrisholt Novice
01. december 2000 - 09:30 #7
Hvor gammel bliver du så ? Gammel nok til at lyve om din alder ? :-)

Jens B
Avatar billede delphi Nybegynder
01. december 2000 - 09:40 #8
34 år, 9 timer, 40 minuter og 32 sec.... +/- et par timer :)

Peter
Avatar billede anold Nybegynder
01. december 2000 - 09:51 #9
Hej Peter
Tilykke med dagen

har du \'Glemt\' spørgsmål 2, eller kan du ikke se det for flødeskummet på fødselsdags lagkagen

Hilsen Anders
Avatar billede borrisholt Novice
01. december 2000 - 09:53 #10
34 lys i den samme lagkage ... hedder det ikke også et bål ?

Jens B
Avatar billede anold Nybegynder
01. december 2000 - 09:55 #11
Jeg kan høre brændvæsnet rykke ud
Er det sprinkleranlæget der er startet??
Avatar billede delphi Nybegynder
01. december 2000 - 09:57 #12
anold> Spørgsmål 2?  Lad mig lige få et link.

Jens> Bare rolig, der er blandet asbest i flødeskummen og jeg har en af Falck\'s bedste brandslukkere liggende ude i bilen.

Peter
Avatar billede anold Nybegynder
01. december 2000 - 10:21 #13
Her er et link som jeg tror at selv du forstår

Når man har \'drag-droppet\' et navn hvordan fjerne man det så fra den listbox man drag\'er fra


Avatar billede borrisholt Novice
01. december 2000 - 10:23 #14
ListBox1.Items.Delete(ListBox1.ItemIndex);
Avatar billede anold Nybegynder
01. december 2000 - 10:28 #15
Ok nu har jeg vist svar på alle mine spørgsmål for denne gang

Jeg vælger at give jer begge point
Delphi fordi han  kom med en konkret løsning på mit problem med hensyn til drag-drop
Borrisholt for løsningen af spørgsmål 2
Hilsen Anders
Avatar billede delphi Nybegynder
01. december 2000 - 10:51 #16
Den løsning er sku\' for nem Jens!  Du sletter kun den ene linie der har focus.  Drag operationen er lavet således at mere end en linie er selected.

Umiddelbart kan du gøre det således:
procedure TMainForm.ListBoxDragDrop(Sender, Source: TObject; X,
  Y: Integer);
Var
  lbReceiver : TListBox;
  lbSource  : TListBox;
  Index      : Integer;
  aStr      : String;
begin
  lbReceiver := Sender As TListBox;  // Listbox der droppes på.
  lbSource  := Source As TListbox;  // Listbox der dragges fra.

  For Index := lbSource.Items.Count-1 Downto 0 Do  // NB: Ned af!
    If lbSource.Selected[Index] Then
      Begin
        aStr := lbSource.Items[Index];
        lbReceiver.Items.Add(aStr);

        lbSource.Items.Delete(Index);  // Ny linie
      End;
end;

Ulempen er her, at i og med der skal slettes bagfra, så overføres dine \'navne\' i omvendt rækkefølge.  Det KAN selvfølgeligt være ligegyldigt eller alternativt kan du sætte din listbox til at være sorteret.  Hvis linierne SKAL overføres i den samme rækkefølge kan du gøre følgende (en dobbeltloop, hvor kopiering foretages først hvorefter loop to sletter linierne):

procedure TMainForm.ListBoxDragDrop(Sender, Source: TObject; X,
  Y: Integer);
Var
  lbReceiver : TListBox;
  lbSource  : TListBox;
  Index      : Integer;
  aStr      : String;
begin
  lbReceiver := Sender As TListBox;  // Listbox der droppes på.
  lbSource  := Source As TListbox;  // Listbox der dragges fra.

  For Index := 0 To lbSource.Items.Count-1 Do 
    If lbSource.Selected[Index] Then
      Begin
        aStr := lbSource.Items[Index];
        lbReceiver.Items.Add(aStr);
      End;

  For Index := lbSource.Items.Count-1 DownTo 0 Do 
    If lbSource.Selected[Index] Then
      lbSource.Items.Delete(Index); 
end;


Delphi
Avatar billede delphi Nybegynder
01. december 2000 - 10:52 #17
Fusk, hans svar på spørgsmål to var \'forkert\'...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester