punker76 / gong-wpf-dragdrop

The GongSolutions.WPF.DragDrop library is a drag'n'drop framework for WPF

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Shift + Click item of multi-selectable Listbox doesn't work as windows file explorer

julia-chen opened this issue · comments

This issue will occur when DragSource is Listbox which SelectionMode is Extend.

For example, there are 100 items in Listbox.

  1. Click at the 10th item.
  2. Press shift-key and select the 5th item.
  3. Press shift-key and select the 7th item.

[Expect Result]
7th item ~ 10th item will be selected

[Actual Result]
only 7th item is selected.

After step 3, if shift + click any item, the result is not the same as in windows file explorer.

DragDrop.DragSource_PreviewMouseLeftButtonUp
{
...
      if (itemsControl != null && m_DragInfo != null && m_ClickSupressItem == m_DragInfo.SourceItem) {
        if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) {
          itemsControl.SetItemSelected(m_DragInfo.SourceItem, false);
        } else {
          itemsControl.SetSelectedItem(m_DragInfo.SourceItem);
        }
      }
...
}

ItemsControlExtensions.SetSelectedItem
{
...
      } else if (itemsControl is ListBox) {
        ((ListBox)itemsControl).SelectedItem = null;
        ((ListBox)itemsControl).SelectedItem = item;
      }
...
}

I modify the code to

DragDrop.DragSource_PreviewMouseLeftButtonUp
{
...
        if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) {
          itemsControl.SetItemSelected(m_DragInfo.SourceItem, false);
        }
        else if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0)
        {
            object selecteditem = null;
            foreach (var item in itemsControl.GetSelectedItems())
            {
                selecteditem = item;
                break;
            }

            if (selecteditem != null)
            {
                itemsControl.SetSelectedItem(selecteditem);

                if (selecteditem != m_DragInfo.SourceItem)
                {
                    bool selectflag = false;
                    object startitem = null, enditem = null;

                    foreach (var item in itemsControl.Items)
                    {
                        if (item == m_DragInfo.SourceItem ||
                            item == selecteditem)
                        {
                            selectflag = true;
                            if (null == startitem)
                                startitem = item;
                            else
                                enditem = item;
                        }

                        if (itemsControl.GetItemSelected(item) != selectflag)
                            itemsControl.SetItemSelected(item, selectflag);

                        if (true == selectflag)
                        {
                            if (enditem == item)
                                selectflag = false;
                        }
                    }
                }
            }
        }
        else
        {
            itemsControl.SetSelectedItem(m_DragInfo.SourceItem);
        }
...
}

ItemsControlExtensions.SetSelectedItem
{
...
      } else if (itemsControl is ListBox) {

          SelectionMode mode = ((ListBox)itemsControl).SelectionMode;

          try
          {   // change SelectionMode for UpdateAnchorAndActionItem
              ((ListBox)itemsControl).SelectionMode = SelectionMode.Single;
              ((ListBox)itemsControl).SelectedItem = null;
              ((ListBox)itemsControl).SelectedItem = item;
          }
          finally
          {
              ((ListBox)itemsControl).SelectionMode = mode;
          }

      }...
}