ListBox поменять местами элементы

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Gogic
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 24.08.2008 (Вс) 13:19

ListBox поменять местами элементы

Сообщение Gogic » 19.12.2011 (Пн) 19:30

Здравствуйте. Возникла задача поменять местами элементы в листбоксе с помощью Drag & Drop

Код: Выделить всё
Private Sub Form_Load()
lst01.AddItem "Item001"
lst01.AddItem "Item002"
lst01.AddItem "Item003"
lst01.AddItem "Item004"
End Sub

Private Sub lst01_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
lst01.OLEDrag
End If
End Sub

Private Sub lst01_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
AllowedEffects = vbDropEffectCopy
Data.Clear
    Data.SetData lst01.List(lst01.ListIndex), vbCFText
End Sub

Private Sub lst01_OLECompleteDrag(Effect As Long)
'Debug.Print "Ready"
End Sub

Private Sub lst01_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Data.GetFormat(vbCFText) = True Then
    Debug.Print X, Y
    Debug.Print "Drop"
    Effect = vbDropEffectCopy
    Else
    Effect = vbDropEffectNone
    End If
End Sub


Так, вот, вопрос, можно ли с помощью координат получить индекс элемента, или все таки придется юзать ListView и метод GetItemAt ?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: ListBox поменять местами элементы

Сообщение Antonariy » 19.12.2011 (Пн) 21:33

Можно. Y известен, высота элемента тоже известна, это TextHeight того шрифта, который настроен в листбоксе. Индекс первого видимого элемента — TopIndex. Дальше банальная арифметика: index = Y \ TextHeight + 1 + TopIndex
Лучший способ понять что-то самому — объяснить это другому.

Gogic
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 24.08.2008 (Вс) 13:19

Re: ListBox поменять местами элементы

Сообщение Gogic » 20.12.2011 (Вт) 10:28

Можно. Y известен, высота элемента тоже известна, это TextHeight того шрифта, который настроен в листбоксе. Индекс первого видимого элемента — TopIndex. Дальше банальная арифметика: index = Y \ TextHeight + 1 + TopIndex



Теперь следует вопрос, как получить TextHeight шрифта. В свойствах lst01.Font такого нет.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: ListBox поменять местами элементы

Сообщение Хакер » 20.12.2011 (Вт) 10:44

Просвети себя на тему того, методом каких контролов явлется TextHeight.

Потом. Ты хочешь менять элементы в пределах одного листбокса D'n'Drop-ом?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Gogic
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 24.08.2008 (Вс) 13:19

Re: ListBox поменять местами элементы

Сообщение Gogic » 20.12.2011 (Вт) 11:20

Просвети себя на тему того, методом каких контролов явлется TextHeight.


Просветил. Как метод он есть разве что у пикчербокса.
Однако, тут имелась в виду функция, а не метод, и я сразу не сообразил, потому что http://bbs.vbstreets.ru/memberlist.php?mode=viewprofile&u=6946 указал в примере ее без параметра.

Потом. Ты хочешь менять элементы в пределах одного листбокса D'n'Drop-ом?


Да.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: ListBox поменять местами элементы

Сообщение Хакер » 20.12.2011 (Вт) 12:08

Ну допустим ты знаешь индекс пункта по координатам курсора. Дальнейшие твои действия при помощью OLE-драгэндропа?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: ListBox поменять местами элементы

Сообщение Debugger » 20.12.2011 (Вт) 14:14

Взять элемент, который тащили, и переставить на место до (или после, смотря к какому краю ближе) того элемента, что под курсором.

djalex777
Постоялец
Постоялец
 
Сообщения: 461
Зарегистрирован: 23.03.2006 (Чт) 16:02

Re: ListBox поменять местами элементы

Сообщение djalex777 » 20.12.2011 (Вт) 14:28

Хакер писал(а):Ну допустим ты знаешь индекс пункта по координатам курсора. Дальнейшие твои действия при помощью OLE-драгэндропа?

В событии DragDrop ставим (добавляем) элемент, который перетаскиваем, на место текущего пункта, после чего удаляем тот элемент, который начали перетаскивать.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: ListBox поменять местами элементы

Сообщение Хакер » 20.12.2011 (Вт) 15:09

Вы оба.
Я не спрашивал, как реализовать перетаскивание просто. Не надо отвечать в таком духе, как будто я не знаю, как это сделать.
Я спрашиваю автора, какая связь между желанием менять местами пункты и OLE-перетаскиванием. Ключевое слово здесь OLE. И я не спрашиваю в исконном смысле слова «спрашивать», я заранее знаю, что он пожмётся, подумает, и придёт к ответу «никакой связи».
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: ListBox поменять местами элементы

Сообщение Antonariy » 20.12.2011 (Вт) 17:20

Debugger писал(а):Взять элемент, который тащили, и переставить на место до (или после, смотря к какому краю ближе) того элемента, что под курсором.
В событии DragDrop ставим (добавляем) элемент, который перетаскиваем, на место текущего пункта, после чего удаляем тот элемент, который начали перетаскивать.

Как все сложно. И как все верят в то, что они действительно "тащат элемент". :) Элементы листбокса это просто строки текста.

Поменять у элементов текст.
Лучший способ понять что-то самому — объяснить это другому.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 20.12.2011 (Вт) 19:30

Antonariy писал(а):Поменять у элементов текст.

Там ещё связанное значение может быть :D
К тому же, они не соседние. Не swap требуется, а перемещение :)

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 20.12.2011 (Вт) 19:40

По теме. WinApi - функция SendMessage c сообщением LB_ITEMFROMPOINT и координатами точки возвращает (в том числе) индекс ближайшего элемента к указанной точке.

WParam: Не используется.
LParam: Младшее слово – x-координата точки, старшее – y-координата. Координаты задаются относительно верхнего левого угла.
Возвращает: Младшее слово - индекс элемента, ближайшего к заданной точке. Старшее слово: 0 – если точка внутри списка, 1 – если точка вне списка.

На всякий случай замечу, что элементы списка теоретически могут иметь разную высоту :)

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re:

Сообщение Antonariy » 20.12.2011 (Вт) 21:24

Qwertiy писал(а):
Antonariy писал(а):Поменять у элементов текст.

Там ещё связанное значение может быть :D
И его, если настаиваешь.
Qwertiy писал(а):К тому же, они не соседние. Не swap требуется, а перемещение :)

И что, что соседние? На что это влияет?
Код: Выделить всё
s = Listbox.List(x)
l = Listbox.ItemData(x)
Listbox.List(x) = Listbox.List(y)
Listbox.ItemData(x) = Listbox.ItemData(y)
Listbox.List(y) = s
Listbox.ItemData(y) = l
Лучший способ понять что-то самому — объяснить это другому.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 20.12.2011 (Вт) 21:48

Antonariy писал(а):И что, что соседние? На что это влияет?

Было:
Код: Выделить всё
Первый
Второй
Третий
А этот тащим на самый верх
Получаем твоим методом:
Код: Выделить всё
А этот тащим на самый верх
Второй
Третий
Первый
а надо
Код: Выделить всё
А этот тащим на самый верх
Первый
Второй
Третий

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: ListBox поменять местами элементы

Сообщение Antonariy » 20.12.2011 (Вт) 21:58

Точно, тупанул я. Их же не поменять местами надо, а сдвиг сделать.
Лучший способ понять что-то самому — объяснить это другому.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: ListBox поменять местами элементы

Сообщение Хакер » 20.12.2011 (Вт) 22:12

Вообще-то в системе уже есть листбокс, поддерживающий драггин элементов списка:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775144%28v=VS.85%29.aspx#drag_list_boxes

И чтобы превратить обычный листбокс в лист-бокс с возможностью драггинга, достаточно одной функции MakeDragList. Да, надо обрабатывать нотификации, отсылаемые родителю. Но зато имеем курсор-вставки в качестве бонуса:
Изображение
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Gogic
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 120
Зарегистрирован: 24.08.2008 (Вс) 13:19

Re: ListBox поменять местами элементы

Сообщение Gogic » 21.12.2011 (Ср) 2:55

Я спрашиваю автора, какая связь между желанием менять местами пункты и OLE-перетаскиванием. Ключевое слово здесь OLE. И я не спрашиваю в исконном смысле слова «спрашивать», я заранее знаю, что он пожмётся, подумает, и придёт к ответу «никакой связи».


Никакой :), взято как пример, листбокс используется как OLE-приемник для других целей.

По теме. WinApi - функция SendMessage c сообщением LB_ITEMFROMPOINT и координатами точки возвращает (в том числе) индекс ближайшего элемента к указанной точке.


За информацию спасибо, с этим вроде как решили.

Вообще-то в системе уже есть листбокс, поддерживающий драггин элементов списка.


Спасибо, то что нужно. Хотя на скрине TreeView вроде, но тоже пригодится :)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: ListBox поменять местами элементы

Сообщение Хакер » 21.12.2011 (Ср) 5:57

На скрине TreeView, потому что скриншота c InsertionMark-ом со списком не нашлось. Текст надо читать, а не на картинки ориентироваться.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот, Yandex-бот и гости: 55

    TopList