I'm trying to implement a drag and drop for multiple items in a list box.
In
my test there are two list boxes, ListBoxLeft and ListBoxRight,
populated with default data. Interaction.DragDropMode = ldmMove,
MultiSelect = True; DragMode = dmAutomatic.
The implementation is in the OnAfterDropItem event. This is the code for the ListBoxLeft.
procedure TfrmMain.ListBoxLeftAfterDropItem(Sender: TObject; AFromItem,
AToItem: TTMSFNCListBoxItem);
var
iSelectedIndex: Integer;
iIndex: Integer;
iCount: Integer;
begin
iCount := ListBoxRight.SelectedItemCount;
for iSelectedIndex := iCount - 1 downto 0 do
begin
iIndex := ListBoxRight.SelectedItems[iSelectedIndex].Index;
ListBoxLeft.AddItem(ListBoxRight.Items[iIndex].Text);
ListBoxRight.Items.Delete(iIndex);
AToItem: TTMSFNCListBoxItem);
var
iSelectedIndex: Integer;
iIndex: Integer;
iCount: Integer;
begin
iCount := ListBoxRight.SelectedItemCount;
for iSelectedIndex := iCount - 1 downto 0 do
begin
iIndex := ListBoxRight.SelectedItems[iSelectedIndex].Index;
ListBoxLeft.AddItem(ListBoxRight.Items[iIndex].Text);
ListBoxRight.Items.Delete(iIndex);
end;
end;
end;
The code for ListBoxRight is similar, with Left and Right swapped.
It
is not working as I expected. With one item selected in a list, I
thought that going into the OnBeforeDropItem, SelectedItemCount for the
source would = 1, and in going into OnAfterDropItem, SelectedItemCount
for the source would equal 0, as the item has now been deleted in the
move. Similarly if 2 items were selected, I expected the could to be 2
before the drop and 1 after the drop.
This is not what I am seeing. SelectItemCount is sometimes changed to account for the first move, and sometimes not.
AFromItem.Index = the item index in OnBeforeDropItem, and -1 in OnAfterDropItem.
If the last item in the list is being moved
iIndex := ListBoxRight.SelectedItems[iSelectedIndex].Index;
generates an AV.
I tried changing
for iSelectedIndex := iCount - 1 downto 0 do
to
for iSelectedIndex := iCount - 2 downto 0 do
This stopped the AVs, but now sometimes misses moving an item, depending on the value in SelectedItemCount.
I
haven't been able to find a pattern to predict when the values in
SelectedItemCount are what I expect and what I sometimes get.
I am missing something, or is there something not quite right in the DragDrop handling ?
TIA
Sue