Я пытаюсь переместить предметы, чтобы изменить их порядок внутри listview
с largeImage style.
Проблемы существуют в методе getItemAt(x, y)
внутри dragdrop
, поскольку этот метод всегда возвращает ноль , только если dragDrop
не выполняется точно над существующим элементом ( Обычно я проваливаюсь между двумя предметами, это более интуитивно понятно imo ).
private void lvPictures_DragDrop(object sender, DragEventArgs e)
{
Point p = lvPictures.PointToClient(new Point(e.X, e.Y));
ListViewItem MovetoNewPosition = lvPictures.GetItemAt(p.X, p.Y);
//MovetoNewPosition is null
}
Итак, суть в том, как получить ближайший элемент, если dragDrop
выполняется между двумя элементами, а не над одним?
Ответ указал мне правильное направление, вот как я реализовал метод «найти ближайший»: (может быть, не идеален, но пока работает)
ListViewItem itemToBeMoved = (e.Data.GetData(typeof(ListView.SelectedListViewItemCollection)) as ListView.SelectedListViewItemCollection)[0];
ListViewItem itemToBeMovedClone = (ListViewItem)itemToBeMoved.Clone();
ListViewItem itemInDropPosition = listView.GetItemAt(p.X, p.Y);
if (itemInDropPosition == null)
{
ListViewItem leftItem = listView.FindNearestItem(SearchDirectionHint.Left, p);
ListViewItem rightItem = listView.FindNearestItem(SearchDirectionHint.Right, p);
if (leftItem == null && rightItem == null)
{
return;
}
else if (leftItem == null)
{
itemInDropPosition = rightItem;
}
else if (rightItem == null)
{
itemInDropPosition = leftItem;
}
else
{
//PGM: appens that if you move to the right or to the left, between two items, the left item (if moving to the right) or the right item (if moving to the left) is wrong, because it select not the first one, but the second
if (rightItem.Index - leftItem.Index > 1 && leftItem.Index < itemToBeMoved.Index && rightItem.Index <= itemToBeMoved.Index)
{
//we are moving to the left
rightItem = listView.Items[rightItem.Index - 1];
}
else if (rightItem.Index - leftItem.Index > 1 && leftItem.Index >= itemToBeMoved.Index && rightItem.Index > itemToBeMoved.Index)
{
//we are moving to the right
leftItem = listView.Items[leftItem.Index + 1];
}
else if (rightItem.Index - leftItem.Index > 1)
{
//significa che è stato spostato sul posto e non va mosso
return;
}
if (Math.Abs(p.X - leftItem.Position.X) < Math.Abs(p.X - rightItem.Position.X))
{
itemInDropPosition = leftItem;
}
else
{
itemInDropPosition = rightItem;
}
}
}