回答 拖动单个/多个选择

aw48

活跃的成员
加入
2013年2月9日
消息
35
地点
德国
编程经验
10+
你好,
我正在使用vs10 c#,framework 4.0
我想将数据从ListView移动到ListBox,但控制类型无关紧要
有人可以解释如何使用相应的事件将所选数据从一个控件移动到另一个控件中的选定数据从一个文件夹到另一个文件夹中的WindowSexplorer中的移动数据。
对于ListView,我将鼠标悬停下来,移动。
对于列表框,我有拖放事件dragenter和dragdrop
请不要邮寄代码,只有描述所需操作的描述。
例如,我拥有的一个问题,我必须在拖放到列表框之前两次单击列表视图项。首先选择项目,第二个开始Draganddrop
任何帮助感激。提前致谢
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
不要发布代码?

好的

好吧,我会将您链接到相关文档,但他们提供代码示例。猜猜这总结了回答这个话题。
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
我将重现以下一些帖子,我在其他地方提交,这可能有助于您了解所涉及的原则以及您可以执行的步骤,以便在任何特定方案中拖放工作。
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
如果您有兴趣执行拖动&在WinForms中删除操作然后我建议您阅读 at least.

我将在两个ListBox之间开始移动项目,这相对简单。

1.创建新的WinForms应用程序项目。
2.将两个ListBox添加到表单中。
3.用以下内容替换现有表单代码:
C#:
public Form1()
{
    InitializeComponent();

    // Hook up the form event handler.
    this.Load += new EventHandler(Form1_Load);
}

private void Form1_Load(object sender, EventArgs e)
{
    // Allow data to be dropped on both ListBoxes.
    this.listBox1.AllowDrop = true;
    this.listBox2.AllowDrop = true;

    // Populate the ListBoxes.
    this.listBox1.Items.AddRange(new string[] {"List 1, Item 1",
                                               "List 1, Item 2",
                                               "List 1, Item 3",
                                               "List 1, Item 4",
                                               "List 1, Item 5"});
    this.listBox2.Items.AddRange(new string[] {"List 2, Item 1",
                                               "List 2, Item 2",
                                               "List 2, Item 3",
                                               "List 2, Item 4",
                                               "List 2, Item 5"});

    // Hook up the ListBox event handlers.
    this.listBox1.MouseDown += new MouseEventHandler(ListBox_MouseDown);
    this.listBox2.MouseDown += new MouseEventHandler(ListBox_MouseDown);
    this.listBox1.DragEnter += new DragEventHandler(ListBox_DragEnter);
    this.listBox2.DragEnter += new DragEventHandler(ListBox_DragEnter);
    this.listBox1.DragDrop += new DragEventHandler(ListBox_DragDrop);
    this.listBox2.DragDrop += new DragEventHandler(ListBox_DragDrop);
}

void ListBox_MouseDown(object sender, MouseEventArgs e)
{
    ListBox source = (ListBox)sender;

    for (int index = 0; index < source.Items.Count; index++)
    {
        // Test whether the mouse location is within an item
        if (source.GetItemRectangle(index).Contains(e.Location))
        {
            // The mouse was depressed on an item so allow a move operation.
            source.DoDragDrop(source, DragDropEffects.Move);

            break;
        }
    }
}

void ListBox_DragEnter(object sender, DragEventArgs e)
{
    ListBox source = (ListBox)sender;

    if (e.Data.GetDataPresent("System.Windows.Forms.ListBox", false) &&
        e.Data.GetData("System.Windows.Forms.ListBox", false) != source)
    {
        // The data being dragged is a ListBox but not the one that was just entered.
        e.Effect = DragDropEffects.Move;
    }
}

void ListBox_DragDrop(object sender, DragEventArgs e)
{
    ListBox source = (ListBox)sender;

    if (e.Data.GetDataPresent("System.Windows.Forms.ListBox", false))
    {
        // Get the ListBox that the data was dragged from.
        ListBox data = (ListBox)e.Data.GetData("System.Windows.Forms.ListBox", false);


        // Make sure we aren't trying to drag from and drop to the same control.
        if (data != source)
        {
            // Get the item that was dragged.
            object item = data.SelectedItem;

            // Remove the item from its original location.
            data.Items.Remove(item);

            // Get the current mouse location relative to the control being dropped on.
            Point location = source.PointToClient(new Point(e.X, e.Y));
            int dropIndex = -1;

            // Find the item over which the mouse was released.
            for (int index = 0; index < source.Items.Count; index++)
            {
                if (source.GetItemRectangle(index).Contains(location))
                {
                    dropIndex = index;

                    break;
                }
            }

            if (dropIndex == -1)
            {
                // The mouse was not released over an item so add the new item to the end.
                source.Items.Add(item);
            }
            else
            {
                // Insert the new item above the item it was dropped on.
                source.Items.Insert(dropIndex, item);
            }
        }
    }
}
4.运行项目并开始拖动和删除。

我会改进这个例子并随着时间的推移而添加更多。如果有任何您的内容,您将特别想看然后发布一个请求,我会看到我是否可以到达它。
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
此示例演示了从Windows资源管理器中拖动一个或多个文件,或者将拖动文件的一些其他应用程序拖动到ListView中。

1.创建新的WinForms项目。
2.将ListView和ImageSist添加到表单中。
3.使用以下代码替换表单的内容:
C#:
public Form1()
{
    InitializeComponent();

    this.Load += new EventHandler(Form1_Load);
}

void Form1_Load(object sender, EventArgs e)
{
    // Initialise the ListView.
    this.listView1.AllowDrop = true;
    this.listView1.Columns.Add("File name");
    this.listView1.Dock = DockStyle.Fill;
    this.listView1.SmallImageList = this.imageList1;
    this.listView1.View = View.Details;

    this.listView1.DragEnter += new DragEventHandler(listView1_DragEnter);
    this.listView1.DragDrop += new DragEventHandler(listView1_DragDrop);
}

void listView1_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent("FileDrop") &&
        (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
    {
        // A file list is being dragged and it can be copied so provide feedback to the user.
        e.Effect = DragDropEffects.Copy;
    }
}

void listView1_DragDrop(object sender, DragEventArgs e)
{
    // The data can only be dropped if it is a file list and it can be copied.
    if (e.Data.GetDataPresent("FileDrop") &&
        (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
    {
        // Get the data.
        string[] filePaths = (string[])e.Data.GetData("FileDrop");

        ListViewItem[] items = new ListViewItem[filePaths.Length];
        string filePath;

        // For each file in the list, create an item, complete with icon.
        for (int index = 0; index < filePaths.Length; index++)
        {
            filePath = filePaths[index];

            if (!this.imageList1.Images.Keys.Contains(filePath))
            {
                // This is the first time this file has been added so add its icon too.
                this.imageList1.Images.Add(filePath,
                                           Icon.ExtractAssociatedIcon(filePath));
            }

            items[index] = new ListViewItem(filePath, filePath);
        }

        // Add the items to the ListView.
        this.listView1.Items.AddRange(items);
    }
}
4.运行该项目。
5.在Windows资源管理器中选择一个或多个文件,然后将它们拖到您的表单上。

塔达!请注意,如前所述,我已经完成了您通常在设计器中执行的设计时间元素的一些设置。为了这个例子,代码比解释更容易做到这一点。
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
我将使用最后一个例子作为向您展示如何建立拖动的基础&删除代码。我现在可以听到人们说的"但我怎么知道使用FileDrop格式,我怎么知道它返回字符串数组"。好吧,我要向你展示你如何工作。

首先,您必须确保您的控件是拖放目标,因此将其allowdrop属性设置为true。接下来,您需要测试数据被拖动的格式可用。要执行GetFormats方法。 GetFormats返回一个字符串数组,因此您可以循环循环以查看您可以在以下内容中获取的格式:
C#:
private void listView1_DragEnter(object sender As Object, DragEventArgs e)
{
    foreach (string format in e.Data.GetFormats())
    {
        MessageBox.Show(format);
    }
}
将数据拖到控件上,它将开始为每种格式突出邮件。您可能更愿意使用console.writeline并在输出窗口中查看列表,因为它不太侵入。

如果您在每个格式中获取数据,您现在需要确定将创建的.NET对象。然后决定哪些对您最有用的数据。为此,您首先需要在每个格式中获取数据,然后测试它的类型:
C#:
private void listView1_DragEnter(object sender, DragEventArgs e)
{
    foreach (string format in e.Data.GetFormats())
    {
        MessageBox.Show(e.Data.GetData(format).GetType().ToString(), format);
    }
}
然后,您可以根据其.NET类型检查每个对象。返回emmemstream的人将更加难以解释,但字符串阵列将很容易检查,因此让我们从它们开始:
C#:
private void listView1_DragEnter(object sender, DragEventArgs e)
{
    string[] strings;

    foreach (string format in e.Data.GetFormats())
    {
        strings = e.Data.GetData(format) as string();

        if (strings != null)
        {
            MessageBox.Show(String.Join(Environment.NewLine,
                                        strings),
                            format);
        }
    }
}
因此,通过拖动多个文件,您现在将知道文件名格式以DOS兼容的格式返回第一个文件的路径,Filenamew格式返回第一个文件的完整路径,FileDrop格式返回完整路径所有文件。在这种情况下,我们需要去,因为所有文件的完整路径正是我们所需要的。我们现在知道我们需要测试我们使用getDatapresent的FileDrop格式,然后以这种格式获取数据,我们使用getData。

这基本上你应该如何拖动& drop operations.
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
1.创建新的Windows窗体项目。
2.将列表框添加到表单中。
3.用以下内容替换表单的现有代码:
C#:
public Form1()
{
    InitializeComponent();

    this.Load += new EventHandler(Form1_Load);
}

private void Form1_Load(object sender, EventArgs e)
{
    // Initialise the ListBox.
    this.listBox1.AllowDrop = true;
    this.listBox1.Items.AddRange(new string[] {"Item 1",
                                               "Item 2",
                                               "Item 3",
                                               "Item 4",
                                               "Item 5"});

    this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
    this.listBox1.DragEnter += new DragEventHandler(listBox1_DragEnter);
    this.listBox1.DragOver += new DragEventHandler(listBox1_DragEnter);
    this.listBox1.DragDrop += new DragEventHandler(listBox1_DragDrop);
}

private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
    // Test whether the mouse is over an item.
    if (this.GetItemIndexAtPoint(e.Location) != -1)
    {
        // The mouse is over an item so start dragging.
        this.listBox1.DoDragDrop(this.listBox1, DragDropEffects.Move);
    }
}

private void listBox1_DragEnter(object sender, DragEventArgs e)
{
    // Test whether the data being dragged is the ListBox itself.
    if (e.Data.GetDataPresent("System.Windows.Forms.ListBox") &&
        e.Data.GetData("System.Windows.Forms.ListBox") == this.listBox1)
    {
        // Get the location of the mouse relative to the ListBox.
        Point mouseLocation = this.listBox1.PointToClient(new Point(e.X, e.Y));

        // Force the location to be within the horizontal bounds of the ListBox.
        if (mouseLocation.X < 0)
        {
            mouseLocation.X = 0;
        }
        else if (mouseLocation.X > this.listBox1.Width)
        {
            mouseLocation.X = this.listBox1.Width;
        }

        // Force the location to be within the vertical bounds of the ListBox.
        if (mouseLocation.Y < 0)
        {
            mouseLocation.Y = 0;
        }
        else if (mouseLocation.Y > this.listBox1.Height)
        {
            mouseLocation.Y = this.listBox1.Height;
        }

        if (this.GetItemIndexAtPoint(mouseLocation) == this.listBox1.SelectedIndex)
        {
            // Don't allow the selected item to be dropped on itself.
            e.Effect = DragDropEffects.None;
        }
        else
        {
            // Allow the selected item to be moved.
            e.Effect = DragDropEffects.Move;
        }
    }
}

private void listBox1_DragDrop(object sender, DragEventArgs e)
{
    // Test whether the data being dragged is the ListBox itself and the selected item can be moved.
    if (e.AllowedEffect == DragDropEffects.Move &&
        e.Data.GetDataPresent("System.Windows.Forms.ListBox") &&
        e.Data.GetData("System.Windows.Forms.ListBox") == this.listBox1)
    {
        int selectedIndex = this.listBox1.SelectedIndex;

        // Get the index of the item being dropped on.
        int dropIndex = this.GetItemIndexAtPoint(this.listBox1.PointToClient(new Point(e.X, e.Y)));

        // If the item being dropped on is below the selected item, the index of the
        // item being dropped on will decrement once the selected item is removed.
        if (dropIndex > selectedIndex)
        {
            dropIndex -= 1;
        }

        object selectedItem = this.listBox1.SelectedItem;

        this.listBox1.Items.Remove(selectedItem);

        if (dropIndex == -1)
        {
            // The item was dropped after the last item so add it at the end of the list.
            this.listBox1.Items.Add(selectedItem);
        }
        else
        {
            // Insert the item above the item it was dropped on.
            this.listBox1.Items.Insert(dropIndex, selectedItem);
        }

        this.listBox1.SelectedItem = selectedItem;
    }
}

private int GetItemIndexAtPoint(Point location)
{
    int itemIndex = -1;

    for (int index = 0; index < this.listBox1.Items.Count; index++)
    {
        // Test whether the location is within an item.
        if (this.listBox1.GetItemRectangle(index).Contains(location))
        {
            itemIndex = index;
            break;
        }
    }

    return itemIndex;
}
4.运行项目并开始拖动。

当您删除项目时,它将被移动到您删除它的项目上方的位置。如果在最后一项之后将其放下,它将移动到列表的末尾。
 

jmplhinney.

C#论坛主持人
工作人员
加入
2011年4月23日
消息
3,719
地点
悉尼,澳大利亚
编程经验
10+
例如,我拥有的一个问题,我必须在拖放到列表框之前两次单击列表视图项。首先选择项目,第二个开始Draganddrop
问题显而易见。当您开始拖动时,您假设您应该只能能够使用所选项目而不会将任何想法放入其中。如果您想成为一个有效的程序员,那么您需要成为一个问题解决者,而不仅仅是代码作家。显然可以解决这一问题的两种可能的方法。首先,当鼠标按钮被抑制时,可以选择项目,而不是使用鼠标按钮释放的鼠标按钮完成点击。这绝对没有拖放并删除任何特定的事情,并且您能够通过配置(设置属性而自动发生)或通过代码来确定这样的事情是否有可能。其次,您无法盲目地使用所选项目并在开始拖动和使用时掉鼠标结束的项目。您可能无法提出完整的解决方案,但您当然可以提出一些让您在那里的一部分的东西。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,889
地点
切萨皮克,va.
编程经验
10+
请不要发布代码,
唉, @jmcilkinney. has posted code. @aw48,一定要跳过帖子#4-7,因为您不想从他的智慧和经验中吸取教训。至于其他当前和未来的论坛读者,让我们为他的贡献鼓掌,帮助他人学习。
 
最佳 底部