Domanda

Ho un TListBox con multiselect ed ExtendedSelect entrambi impostati su true. Devo essere in grado di trascinare più elementi nella casella di riepilogo per riorganizzarli. Il mio problema è ciò che accade quando l'utente fa clic su un elemento che è già selezionato senza tenere premuto il tasto CTRL o MAIUSC.

Caso 1: DragMode è impostato su dmManual La selezione viene cancellata prima del mouse verso il basso. Ciò non consentirà di trascinare più elementi.

Caso 2: DragMode è impostato su dmAutomatic L'evento MouseDown non si attiva mai. La selezione non viene cancellata, quindi il trascinamento è OK, ma l'utente non può cancellare la selezione facendo clic su uno degli elementi selezionati. Ciò causa davvero un problema se tutti gli elementi sono selezionati o l'elemento successivo che l'utente desidera selezionare faceva parte della selezione corrente.

Si noti che questo problema si verifica solo se si assegna qualcosa a DragObject nella procedura OnStartDrag. Penso che il problema sparirebbe se OnStartDrag si avvia solo dopo che l'utente sposta il mouse. Ho Mouse.DragImmediate: = false impostato ma continuo ad avviare StartDrag non appena faccio clic su un elemento nella casella di riepilogo.

Sto usando Delphi 7 per questo progetto ma vedo lo stesso comportamento in Delphi 2007.

È stato utile?

Soluzione 4

Non sono sicuro del motivo per cui questo fa la differenza, ma se cambio DragObject in TDrag Control ObjectEx (anziché TDragObjectEx) ottengo il comportamento che sto cercando. La modalità di trascinamento è impostata su Automatico.

Ho provato a guardare e vedere cosa stava influenzando, ma non sono riuscito a capirlo.

Altri suggerimenti

Ci ho giocato per un po '. E osserva gli stessi effetti.

Vorrei utilizzare Case2 e aggiungere un pulsante (Seleziona tutto / Deseleziona tutto) all'elenco. Aggiunge persino funzionalità extra e risolve la parte più fastidiosa del problema.

Usa il caso 2 e quando viene generato l'evento TListBox.OnMouseUp controlla se sono stati selezionati e trascinati più elementi. Se sono selezionati più elementi, ma non sono stati trascinati, deselezionare tutti gli elementi a parte l'elemento selezionato.

Vorrei usare questo metodo perché Windows Explorer funziona in questo modo.

Bit of a kludge ma funziona. DragMode su ListBox è impostato su dmAutomatic.

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  iDropIdx, i: Integer;
  pDropPoint: TPoint;
  slSelected: TStrings;
begin
  {Which item is being dropped onto?}
  pDropPoint := Point(X, Y);
  iDropIdx := ListBox1.ItemAtPos(pDropPoint, False);

  slSelected := TStringList.Create;
  try
    {Copy the selected items to another string list}
    for i := 0 to Pred(ListBox1.Items.Count) do
    begin
      if (ListBox1.Selected[i]) then
        slSelected.Append(ListBox1.Items[i]);
    end;

    {Find the selected items in the listbox and swap them with the drop target}
    for i := 0 to Pred(slSelected.Count) do
    begin
      ListBox1.Items.Exchange(ListBox1.Items.IndexOf(slSelected[i]), iDropIdx);
      inc(iDropIdx);
    end;
  finally
    slSelected.Free;
  end;
end;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top