如何实现拖放

本文关键字:拖放 实现 何实现 | 更新日期: 2023-09-27 18:29:47

我正在做一个项目。这是我现在拥有的代码。

   namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            listBox1.DoDragDrop(listBox1.SelectedItem.ToString(), DragDropEffects.Move);
        }
        private void listBox2_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.AllowedEffect;
        }
        private void listBox2_DragDrop(object sender, DragEventArgs e)
        {
            listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
            listBox1.Items.Remove(listBox1.SelectedItem.ToString());
        }

它可以让你添加到第二个列表框中,但我正在尝试将它放在那里,如果你愿意,你也可以将项目移回第一个列表框。我是像第一个一样重复第二个名单框的代码,还是有一行代码我可以添加。此外,你如何判断你的程序是否"牢不可破"。谢谢

如何实现拖放

我重复第二个列表框的代码吗

差不多,是的。尽管您可以简化它一点,因为代码本质上是相同的,方法是让两个列表框对MouseDown、DragEnter和DragDrop使用相同的处理程序,然后使用发送方来确定它是listBox1还是listBox2。

此外,您可能需要考虑您的MouseDown处理程序。大多数用户不会期望一次点击就能立即开始拖动操作。通常,在开始拖动之前,您会先向下查找鼠标,然后在按钮向下时查找鼠标移动。

我通常做的事情是这样的:

private Size dragSize = SystemInformation.DragSize;
private Rectangle dragBounds = Rectangle.Empty;
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
   if (e.Button == MouseButtons.Left)
   {
        dragBounds = new Rectangle(new Point(e.X - dragSize.Width / 2, e.Y - dragSize.Height/2), dragSize);
   }
   else
   {
       dragBounds = Rectangle.Empty;
   }
}
private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && dragBounds != Rectangle.Empty && !dragBounds.Contains(e.X, e.Y))
    {
        //start drag
        listBox1.DoDragDrop(listBox1.SelectedItem.ToString(), DragDropEffects.Move);
        dragBounds = Rectangle.Empty;
    }
}

对于实现drag&drop:是的,您需要为listbox1和listbox2创建处理程序,以镜像您已经拥有的功能:

  • listBox2的MouseDown事件处理程序
  • listBox1的DragEnter处理程序
  • listBox1的DragDrop处理程序

此外,您还需要确保将这些处理程序分配给表单设计器中它们各自的事件。

可以获取代码,但我不想这样做。你的是一个边缘案例;很多方法中只有一行。但每当我看到代码中的重复时,它就会向我发出信号,表明我需要把代码从其他地方提取出来。如果重复在同一个类中,请将其移动到该类上自己的方法中。如果重复是在不同的类中,要么在两个类之外找到另一个有意义的类来放置新方法,要么考虑创建一个两个类都可以共享的新类。在你的情况下,如果我决定移动代码,我会做这样的事情:

private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
    HandleMouseDown(listbox1);
}
private void listBox2_DragEnter(object sender, DragEventArgs e)
{
    HandleDragEnter( e );
}
private void listBox2_DragDrop(object sender, DragEventArgs e)
{
    HandleDragDrop( listBox1, listBox2, e );
}
private void listBox2_MouseDown(object sender, MouseEventArgs e)
{
    HandleMouseDown(listBox2);
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
    HandleDragEnter( e );
}
private void listBox1_DragDrop(object sender, DragEventArgs e)
{
    HandleDragDrop( listBox2, listBox1, e );
}

private void HandleMouseDown( ListBox listBox )
{
    listBox.DoDragDrop(listBox.SelectedItem.ToString(), DragDropEffects.Move);
}
private void HandleDragEnter( DragEventArgs e )
{
    e.Effect = e.AllowedEffect;
}
private void HandleDragDrop( ListBox src, ListBox dst, DragEventArgs e )
{
    dst.Items.Add( e.Data.GetData(DataFormats.Text) );
    src.Items.Remove( src.SelectedItem.ToString() );
}

移动代码的好处是,如果这些方法增长到不止一行,您可以只在一个地方更改它们。当然,对于单行方法,我还记得以后我总是可以将其移动到自己的方法。我个人倾向于保留两种单行方法,即复制&粘贴第二个列表框,并像上面所做的那样将DragDrop处理程序拆分为自己的方法。