2015-10-22 47 views
1

我有一系列的拖放活動都可以在我的測驗中正常工作。 (從回答問題到選擇頭像)使用類方法拖放

有很多重複的代碼,我想這會更好地從類實現,每次使用拖放時調用該方法。

首先可以這樣做嗎?其次,我需要一種新的拖放方法嗎?

任何想法或粗略的想法都會很棒。

private void pictureBox2_MouseDown(object sender, MouseEventArgs e) 
{ 
pictureBox2.DoDragDrop(pictureBox2.Image, DragDropEffects.Copy); 
} 

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

private void panel1_DragDrop(object sender, DragEventArgs e) 
{ 
    //Set background image of panel to selected avatar' 
    panel1.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap); 
} 
+0

是Web窗體還是Windows Win Forms應用程序? –

+0

窗體窗體應用程序 –

+0

你可以給一些代碼作爲例子重複,你會喜歡重構嗎? – Kapoor

回答

2

如果你想要的是,以避免重複幾個控件的同樣的事件,你應該使用的常見事件:

private void commonPBox_MouseDown(object sender, MouseEventArgs e) 
{ 
    PictureBox PB = sender as PictureBox; 
    if (PB == null) return; //or throw an exception 

    PB.DoDragDrop(PB.Image, DragDropEffects.Copy); 
} 

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

private void commonPanel_DragDrop(object sender, DragEventArgs e) 
{ 
    Panel Pan = sender as Panel; 
    if (Pan == null) return; //or throw an exception 

    //Set background image of panel to selected avatar 
    Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap); 
} 

選擇相應的控制和輸入事件名稱到相應的事件名稱插槽屬性選項卡的事件窗格。

請注意我如何將sender事件的參數轉換爲觸發事件的控件的類型引用。如果演員出錯,參考設置爲null

如果你想要更多的控制,你可以考慮建立一個DragAndDropcontroller類的更多的flexibilty ..:

static class DnDCtl 
{ 
    static List<Control> Targets = new List<Control>(); 
    static List<Control> Sources = new List<Control>(); 

    static public void RegisterSource(Control ctl) 
    { 
     if (!Sources.Contains(ctl)) 
     { 
      Sources.Add(ctl); 
      ctl.MouseDown += ctl_MouseDown; 
     } 
    } 

    static public void UnregisterSource(Control ctl) 
    { 
     if (Sources.Contains(ctl)) 
     { 
      Sources.Remove(ctl); 
     } 
    } 

    static public void RegisterTarget(Control ctl) 
    { 
     if (!Targets.Contains(ctl)) 
     { 
      Targets.Add(ctl); 
      ctl.DragEnter += ctl_DragEnter; 
      ctl.DragDrop += ctl_DragDrop; 
      ctl.AllowDrop = true; 
     } 
    } 

    static public void UnregisterTarget(Control ctl) 
    { 
     if (Targets.Contains(ctl)) 
     { 
      Targets.Remove(ctl); 
      ctl.DragEnter -= ctl_DragEnter; 
      ctl.DragDrop -= ctl_DragDrop; 

     } 
    } 

    static void ctl_MouseDown(object sender, MouseEventArgs e) 
    { 
     PictureBox PB = sender as PictureBox; 
     if (PB != null) PB.DoDragDrop(PB.Image, DragDropEffects.Copy); 

     Panel Pan = sender as Panel; 
     if (Pan != null) Pan.DoDragDrop(Pan.BackgroundImage, DragDropEffects.Copy); 
    } 

    static void ctl_DragEnter(object sender, DragEventArgs e) 
    { 
     e.Effect = DragDropEffects.Copy; 
    } 

    static void ctl_DragDrop(object sender, DragEventArgs e) 
    { 
     Panel Pan = sender as Panel; 
     if (Pan != null) Pan.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap); 

     PictureBox PB = sender as PictureBox; 
     if (PB != null) PB.BackgroundImage = (Image)e.Data.GetData(DataFormats.Bitmap); 
    } 
} 

注:

  • 我有編碼對稱行動爲​​和PictureBoxes展示如何可以處理不同的控制。
  • 我已創建但未使用Lists的來源和目標。對於更復雜的項目,您會發現它們很有用。
  • 我已經編碼了RegisterUnregister方法。您可以在某些情況下注冊並在不再適用時取消註冊
  • 此類控制器適用於動態降低或不允許拖動&降低控制權,當你動態創建它們時。
  • 您也可以繞過代表來解耦來自控制器的拖動操作。

另請注意,有些人有時更喜歡使用MouseMove事件而不是MouseDown尤其如此。因爲它不會很容易干擾選擇。

ListView有一個專門的事件,而不是ListView.ItemDrag,這顯然應該在註冊時使用!

+0

是的,我認爲這是我想到的控制器,我將不得不練習這個。感謝您提供非常有用的反饋和解釋。 –

+0

對不起,我是一個完整的noob,我該如何接受答案? –

+0

TaW非常感謝您的幫助,我設法得到了適用於我的拖放操作的常用控件。我還有一個問題。 我可以將此代碼放入一個類,並跨越多個不同的形式使用它? –