簡體   English   中英

如何實現拖放

[英]How to implement Drag and Drop

我正在做一個項目。 拖放完成后,這就是我現在擁有的代碼。

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

它使您可以添加到第二個列表框,但是我嘗試將其添加到該位置,如果需要,還可以將其移回第一個列表框。 我是否像在第一個列表框中那樣重復第二個列表框的代碼,或者是否可以添加一行代碼?如何判斷程序是否“牢不可破”? 謝謝。

對於實現拖放的主要問題:是的,您需要為listbox1和listbox2創建處理程序,以鏡像您已經擁有的功能:

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

另外,您還需要確保在表單設計器中分配了這些處理程序以用於它們各自的事件。

我是否重復第二個列表框的代碼

是的,是的。 盡管您可以簡化一下代碼,因為通過使兩個列表框對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;
    }
}

可以重新編寫代碼,但是我不想這樣做。 你的是一個極端案例; 許多只包含一行的方法。 但是,每當我看到代碼重復時,就會向我發出信號,表明我需要將該代碼拉到其他地方。 如果重復在同一個類中,則將其移至該類上自己的方法。 如果重復是在單獨的類中,則可以在兩個類之外找到另一個放置新方法的類,或者考慮創建兩個類可以共享的新類。 在您的情況下,如果我決定移動代碼,則將執行以下操作:

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處理程序拆分為自己的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM