【问题标题】:C# ListView DragDrop - Multiple drag and drop methodsC# ListView DragDrop - 多种拖放方法
【发布时间】:2013-01-30 16:26:53
【问题描述】:

我有两个 ListView。一个选项可以拖入另一个选项。这是“字段”ListView。另一个是“builder” ListView。我遇到的问题是,我不能将 ListViewItem 插入到用户拖动它的位置,并且如果他们将其拖动到空白处,也不能将其添加到底部。我可以在这个时候做一个或另一个。我需要一个解决方案。

private void builder_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void fields_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void fields_ItemDrag(object sender, ItemDragEventArgs e)
{
    fromBuilder = false;
    fields.DoDragDrop(e.Item, DragDropEffects.Move);
}

private void builder_ItemDrag(object sender, ItemDragEventArgs e)
{
    fromBuilder = true;
    builder.DoDragDrop(e.Item, DragDropEffects.Move);
}

private void builderAndFields_DragDrop(object sender, DragEventArgs e)
{
    ListViewItem i = new ListViewItem();
    i = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;

    // Since this function works for both the builder and the fields,
    // we have to check to see where we are dropping, the sender
    // is the ListView we are dropping onto
    if (sender.Equals(builder))
    {
        ListViewItem c = new ListViewItem();
        c = (ListViewItem)i.Clone();
        Point cp = builder.PointToClient(new Point(e.X, e.Y));
        Console.WriteLine("cp: " + cp);
        ListViewItem dragToItem = builder.GetItemAt(cp.X, cp.Y);
        Console.WriteLine("dragToItem: " + dragToItem);
        int dropIndex = dragToItem.Index;
        // Now, we have to check to see if we are reordering or adding
        // So, we check the flag to see if the dragDrop was initiated 
        // on the builder or on the fields ListView
        if (fromBuilder)
        {
            builder.Items.Insert(dropIndex, c);
            builder.Items.Remove(i);
        }
        else
        {
            // ## Problem - Attempted solution ##
            if (String.IsNullOrWhiteSpace(dragToItem.ToString()))
                builder.Items.Add(c);
            else
            {
                Console.WriteLine(dropIndex);
                builder.Items.Insert(dropIndex, c);
            }
        }
    }
    // If the sender is the fields listView, the user is trying to remove
    // the item from the builder.
    else
    {
        builder.Items.Remove(i);
    }
}

【问题讨论】:

  • 您不必处理 GetItemAt() 返回 null 的可能性。导致的异常被吞噬。您需要改用 ListView.HitTest()。

标签: c# drag-and-drop


【解决方案1】:

感谢您的评论,汉斯。这很有帮助!这是我遇到的两个问题的解决方案。另一个是能够重新排序 ListView 并将项目拖到列表底部。

// Generic DragEnter
private void ddEnter_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

// ItemDrag Events
private void fields_ItemDrag(object sender, ItemDragEventArgs e)
{
    fromBuilder = false;
    fields.DoDragDrop(e.Item, DragDropEffects.Move);
}

private void builder_ItemDrag(object sender, ItemDragEventArgs e)
{
    fromBuilder = true;
    packetBuilder.DoDragDrop(e.Item, DragDropEffects.Move);
}

// DragDrop Events
private void builderAndFields_DragDrop(object sender, DragEventArgs e)
{
    ListViewItem i = new ListViewItem();
    i = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;

    // Since this function works for both the builder and the fields,
    // we have to check to see where we are dropping, the sender
    // is the ListView we are dropping onto
    Console.WriteLine(sender.Equals(packetBuilder));
    if (sender.Equals(packetBuilder))
    {
        ListViewItem c = new ListViewItem();
        c = (ListViewItem)i.Clone();
        Point cp = packetBuilder.PointToClient(new Point(e.X, e.Y));
        // Now, we have to check to see if we are reordering or adding
        // So, we check the flag to see if the dragDrop was initiated 
        // on the builder or on the fields ListView
        Console.WriteLine(fromBuilder);
        if (fromBuilder)
        {
            if (packetBuilder.HitTest(cp).Location.ToString() == "None")
            {
                packetBuilder.Items.Add(c);
                packetBuilder.Items.Remove(i);
            }
            else
            {
                ListViewItem dragToItem = packetBuilder.GetItemAt(cp.X, cp.Y);
                int dropIndex = dragToItem.Index;
                packetBuilder.Items.Insert(dropIndex, c);
                packetBuilder.Items.Remove(i);
            }

        }
        else
        {
            if (packetBuilder.HitTest(cp).Location.ToString() == "None")
                packetBuilder.Items.Add(c);
            else
            {

                ListViewItem dragToItem = packetBuilder.GetItemAt(cp.X, cp.Y);
                int dropIndex = dragToItem.Index;
                packetBuilder.Items.Insert(dropIndex, c);
            }
        }
    }
    // If the sender is the fields listView, the user is trying to remove
    // the item from the builder.
    else
    {
        packetBuilder.Items.Remove(i);
    }
} 

【讨论】:

  • 我尝试操作我的列表视图项目,但项目的索引没有更新。您是否每次都重新创建列表?
  • 不,我没有每次都重新创建列表。我没有遇到列表索引的问题,但也许是因为我没有使用它们。我不记得了。你能提供一个你在做什么的例子,让我看看吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 2017-05-14
  • 2016-08-26
相关资源
最近更新 更多