ListView drag drop reorder?
От: Sm0ke Россия ksi
Дата: 28.11.21 06:03
Оценка:
Помогите добавить возможность изменения порядка элементов в контроле ListView, путём перетаскивания их мышкой. Когда зажали и потащили элемент, то должна рисоваться горизонтальная линия, указывающая на место инсерта. Если отпустили ЛКМ в новом месте, то нужно получить сообщение о том, что позиция элемента изменилась (чтобы обновить прочие связанные данные). Событие должно содержать прежнюю позицию элемента и новую. Но если перетаскивание отменено по клавише Escape, или итем остался на прежнем месте, то ничего не менять. Ну и конечно при наведении на верх/низ списка с прокруткой нужно его прокручивать (видимо с шагом по таймеру).

В поисках золотой пули. Хочется просто подключить готовую include и вызвать функцию типа LibEnableReorder(wnd_list, TRUE); А не хардкодить всё самому

По этому пуля нужна не серебряная, не охота сражаться оборотнями.

Стили списка:
(WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
LVS_REPORT | LVS_EDITLABELS | LVS_NOSORTHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL)

Расширенные стили:
(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_DOUBLEBUFFER)

Исходники на github: https://github.com/deemetrius/copycat
Re: ListView drag drop reorder?
От: Carc Россия https://vk.com/gosha_mazov
Дата: 28.11.21 09:20
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Помогите добавить возможность изменения порядка элементов в контроле ListView, путём перетаскивания их мышкой. Когда зажали и потащили элемент, то должна рисоваться горизонтальная линия, указывающая на место инсерта. Если отпустили ЛКМ в новом месте, то нужно получить сообщение о том, что позиция элемента изменилась (чтобы обновить прочие связанные данные). Событие должно содержать прежнюю позицию элемента и новую. Но если перетаскивание отменено по клавише Escape, или итем остался на прежнем месте, то ничего не менять. Ну и конечно при наведении на верх/низ списка с прокруткой нужно его прокручивать (видимо с шагом по таймеру).


S>В поисках золотой пули. Хочется просто подключить готовую include и вызвать функцию типа LibEnableReorder(wnd_list, TRUE); А не хардкодить всё самому


S>По этому пуля нужна не серебряная, не охота сражаться оборотнями.


S>Стили списка:

S>(WS_TABSTOP | WS_VISIBLE | WS_CHILD | WS_BORDER |
S> LVS_REPORT | LVS_EDITLABELS | LVS_NOSORTHEADER | LVS_SHOWSELALWAYS | LVS_SINGLESEL)

S>Расширенные стили:

S>(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_DOUBLEBUFFER)

S>Исходники на github: https://github.com/deemetrius/copycat

Чего там писать-то?

  • LVN_BEGINDRAG обрабатываем: и знаем какой (какие) элемент[ы] потащили

  • WM_MOUSEMOVE обрабатываем: и знаем происходит ли перетаскивание в данный момент или нет (запоминаем в обработчике LVN_BEGINDRAG).
    Коли происходит перетаскивание, кажем в ListView линиё через LVM_SETSELECTIONMARK

  • WM_LBUTTONUP обрабатываем: опять же знаем в режиме ли перетаскивания произошло, и знаем над каким элементом ListView отпустили мыша.

    Ну и получаем на шаге 3 информацию: какой (какие) элемент тащили, и над каким отпустили.
    Далее везде… Далее уже по этой инфе обрабатываем бизнес-логику, ну и обновляем сам ListView…

    Делов-то, на час работы.
    Да и то, цельный час, это только если
  • а) код ListView чужой, и поменять его нельзя (подсабкласситься в ListView придёться) и
  • б) вскяки мелочи да красотульки прилепить вроде WM_MOUSELEAVE, SetCapture, WM_CAPTURECHANGED и прочия баловства и иже ними.
  • Aml Pages Home
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.