28. august 2008 - 13:23
Der er
7 kommentarer og
1 løsning
Listbox i Delphi7
Er der nogen der ved hvordan man sætter property i en listbox således at bruger med musen kan flytte items op og/eller ned. Hvis det ikke kan lade sig gøre er der så nogen der ved om der findes en component med denne mulighed.
28. august 2008 - 13:33
#1
Tænker du på at rearrangere dem? Kunne også forestille mig, at du ville scrolle ved at holde fast på en linje.
Tror godt det kan lade sig gøre med TListBox, men ellers kan TListView garanteret. Skal prøve lidt inden der kommer kød på svaret.
28. august 2008 - 23:55
#5
Mit eksempel ser sådan ud (ignorér OutputDebugString-linjerne):
uses
TypInfo;
type
TMyDragObject = class(TDragObject)
private
fSelectedIndex: integer;
public
constructor Create(const aSelectedIndex: integer);
property SelectedIndex: integer read fSelectedIndex;
end;
{ TMyDragObject }
constructor TMyDragObject.Create(const aSelectedIndex: integer);
begin
inherited Create;
fSelectedIndex := aSelectedIndex;
end;
procedure TfrmMain.lbDataDragDrop(Sender, Source: TObject; X, Y: Integer);
var
Index: integer;
begin
Index := (Sender as TListBox).ItemAtPos(Point(X,Y),true);
if Index >= 0 then
(Sender as TListBox).Items.Move((Source as TMyDragObject).SelectedIndex,Index);
OutputDebugString(pchar(format('Drop: Sender: %s, Source: %s (%d,%d)',[Sender.ClassName, Source.ClassName, X, Y])));
Source.Free;
end;
procedure TfrmMain.lbDataDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
// OutputDebugString(pchar(format('Over: Sender: %s, Source: %s (%d,%d) - %s',[Sender.ClassName, Source.ClassName, X, Y, GetEnumName(TypeInfo(TDragState),integer(State))])));
end;
procedure TfrmMain.lbDataEndDrag(Sender, Target: TObject; X, Y: Integer);
begin
if assigned(Target) then
OutputDebugString(pchar(format('End: Sender: %s, Target: %s (%d,%d)',[Sender.ClassName, Target.ClassName, X, Y])))
else
OutputDebugString(pchar(format('End: Sender: %s, Target: %s (%d,%d)',[Sender.ClassName, 'nil', X, Y])));
end;
procedure TfrmMain.lbDataStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
// Det bekymrer mig lidt at dette event kaldes så snart jeg vælger en linje
// i listboksen. Der bliver altså oprettet et objekt, men slipper jeg linjen
// igen, bliver DragDrop aldrig kaldet og objektet (Source = DragObject)
// bliver ikke frigivet.
OutputDebugString(pchar(format('Start: Sender: %s',[Sender.ClassName])));
with (Sender as TListBox) do
if ItemIndex >= 0 then
DragObject := TMyDragObject.Create(ItemIndex);
end;
30. august 2008 - 20:59
#7
Velbekomme. Har altid syntes det drag-drop sjov fungerede ret dårligt og trængte til lidt træning udi det. Jeg synes ikke meget om About's eksempel, da det indeholder globale variable og den slags. På den anden side er det en simpel løsning der virker.
Jeg selv ved ikke hvad der sker med de objekter der oprette, når bare der en linje vælges, for de ender aldrig i OnDragDrop hvor de frigives.
30. august 2008 - 22:04
#8
Nu står der "form level" jo ud for den var i About's kode, så jeg tolker det som en forkortet måde at angive på at den variabel bør være en del af formen - det er jo ikke en hel Unit.
Det vil ikke have nogen funktionel forskel, da man alligevel ikke kan dragge fra to steder på samme tid, men det er jo så en anden sag.
Jeg kiggede i øvrigt lidt i VCL'et (Controls.pas), og det ser ud som om den bruger en global variabel til at gemme det aktuelle DragObject. Jeg kan ikke finde nogles Frees el. lign. på den - kun et par assignments - så jeg ved ikke helt hvad der er meningen i den situation du skriver.