3

是否有可能告诉我List<>上下移动元素的最佳方式。

例如,我有一个名为 Building 的类,而 Building 有一个 Rooms 对象列表List<Room>。房间按名称添加到建筑物中,但我使用此结构生成树视图。用户可以选择在建筑物内上下移动房间。

我试图使用.Reverse(index, count),但这似乎没有做任何事情:

// can this item actually be moved up (is it at the first position in it's current parent?)
if (moveDirection == MoveDirection.UP)
{
    int roomIndex = parentBuilding.Rooms.IndexOf(room);

    if (roomIndex == 0)
    {
        return;
    }
    else
    {
        // move this room up.                            
        parentBuilding.Rooms.Reverse(roomIndex, 1);
    }
}
4

6 回答 6

11

创建一个列表扩展。调用为List<T>.Move(1, MoveDirection.Up).

public static class ListExtensions
{
    public static void Move<T>(this IList<T> list, int iIndexToMove, 
        MoveDirection direction)
    {

        if (direction == MoveDirection.Up)
        {
            var old = list[iIndexToMove - 1];
            list[iIndexToMove - 1] = list[iIndexToMove];
            list[iIndexToMove] = old;
        }
        else
        {
            var old = list[iIndexToMove + 1];
            list[iIndexToMove + 1] = list[iIndexToMove];
            list[iIndexToMove] = old;
        }
    }
}

public enum MoveDirection
{
    Up,
    Down
}

需要考虑的事项

  • 异常处理——如果你试图向下移动底部元素或向上移动顶部元素怎么办?你会得到一个超出范围的索引,因为你不能向上或向下移动它们。

  • 您可以通过将功能扩展到将顶部元素移动到底部元素并将底部元素向下移动到顶部元素等来改进这一点并防止处理异常。

于 2013-02-28T10:56:55.020 回答
4

只需进行交换:

int roomIndex = parentBuilding.Rooms.IndexOf(room);

if (roomIndex == 0)
{
    return;
}
else
{
    // move this room up.                            
    var temp = parentBuilding.Rooms[index-1];
    parentBuilding.Rooms[index-1] = parentBuilding.Rooms[index];
    parentBuilding.Rooms[index] = temp;
}
于 2013-02-28T10:57:37.547 回答
1

就个人而言,我会做扩展方法:

static void Swap<TSource>(this IList<TSource> source, int fromIndex, int toIndex)
{
    if (source == null)
        throw new ArgumentNullExcpetion("source");

    TSource tmp = source[toIndex];
    source[toIndex] = source[fromIndex];
    source[fromIndex] = tmp;
}

用法:

if (moveDirection == MoveDirection.UP)
{
    int roomIndex = parentBuilding.Rooms.IndexOf(room);

    if (roomIndex == 0)
    {
        return;
    }
    else
    {
        // move this room up.                            
        parentBuilding.Rooms.Swap(roomIndex, roomIndex - 1);
    }
}
于 2013-02-28T10:58:54.153 回答
0

如何使用SortedDictionary<int, Room>而不是列表。您可以将索引存储为字典的键,并在需要时交换值。

于 2013-02-28T10:53:37.680 回答
0

与上面的房间交换位置应该这样做:

int roomIndex = parentBuilding.Rooms.IndexOf(room);

if (roomIndex == 0)
{
    return;
}

var wasAbove = parentBuilding.Rooms[roomIndex - 1];
parentBuilding.Rooms[roomIndex - 1] = room;
parentBuilding.Rooms[roomIndex] = wasAbove;

也就是说,我不确定这是否是适合这种情况的最佳对象模型;目前尚不清楚列表中房间的顺序是否起作用,也不清楚如何“向上移动”房间——这是什么意思?

最好有一个RoomPlacement类来聚合一个房间和足够的信息来定位它,并使用它来代替。

于 2013-02-28T10:55:22.680 回答
0

试试这个:

int newIndex = whateverIndexYouWantItAt;

int oldIndex = parentBuilding.Rooms.IndexOf(room);
var item = parentBuilding.Rooms[oldIndex];

list.RemoveAt(oldIndex);

if (newIndex > oldIndex) newIndex--; 

parentBuilding.Rooms.Insert(newIndex, item);
于 2013-02-28T10:55:59.867 回答