如何实现拖放

时间:2012-04-03 13:44:09

标签: c# winforms

我正在开展一个项目。拖放这是我现在的代码。

   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());
        }

它允许您添加到第二个列表框,但我试图获取它,如果您愿意,您也可以将项目移回第一个列表框。我是否像第一个列表框那样重复第二个列表框的代码,或者我可以添加一行代码。如何判断您的程序是否“牢不可破”。感谢。

3 个答案:

答案 0 :(得分:2)

关于实施拖拉的主要问题drop:是的,你需要为listbox1和listbox2创建镜像你已经拥有的功能的处理程序:

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

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

答案 1 :(得分:2)

  

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

差不多,是的。虽然你可以稍微简化它,因为代码将基本相同,因为两个列表框都使用相同的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;
    }
}

答案 2 :(得分:1)

可以重新编写代码,但我倾向于不想这样做。你的是一个边缘案例;很多只有一行的方法。但是每当我看到代码中的重复时,它就会向我发出信号,我需要将代码拉出其他地方。如果重复在同一个类中,则将其移动到类中自己的方法。如果重复是在单独的类中,要么在两者之外找到另外一个放置新方法的类,要么考虑创建两个类可以共享的新类。在你的情况下,如果我决定移动代码,我会做这样的事情:

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处理程序拆分为自己的方法,如上所述。