當產品間需要交互實現數據傳遞,或產品需要從外部導入文件時,通過控件拖拽來實現是個不錯的選擇。在UI上支持控件拖拽,可極大提升用戶體驗。
拖拽本身并不神秘,它的本質實際是一個數據交換的過程。控件接受從其他地方來的數據,并進行處理。數據交換有多種方法,Windows中剪貼板可能就是用的最多,但最不被注意的一種方法。
下面介紹用C#實現控件拖拽,并通過剪切板交換數據。
控件拖拽觸發/響應函數
對于拖拽的對象,需要在MouseDown或ItemDrag中調用DoDragDrop,傳遞要拖拽的數據對象并觸發拖拽。總的來說,當用戶調用DoDragDrop方法后,就進入到一個循環中。 循環會一直跟蹤鼠標,檢查鼠標所在的窗體是否實現IDropTarget,如果實現了則:調用DropEnter,并通過調用GiveFeedBack來顯示效果;鼠標在控件上時,調用DropOver,也是通過GiveFeedBack來顯示效果;在拖拽過程中,鍵盤或鼠標按鍵發生變化,可以通過QueryContinueDrag來檢查是否能繼續操作,根據不同的返回結果,調用DropOver或DropLeave;鼠標釋放時觸發DragDrop事件,執行拖拽邏輯。
-
DragEnter、DragOver、DragLeave事件
觸發: 當用鼠標拖拽一個對象到控件的窗口時,首先觸發DragEnter,然后是DragOver,拖放對象懸浮于拖放區域,在拖放區域內移動時多次觸發DragOver,當離開窗體時觸發DragLeave。
作用: 設置判斷對象是否是要接受的類型以及鼠標的樣式。 -
DragDrop事件
觸發: 當用戶拖拽對象到控件上,并釋放時觸發。
作用: 接受拖拽數據,實現拖拽邏輯
實現控件拖拽的典型流程
-
設置AllowDrop
在對一個控件進行拖拽編程時,我們必須把AllowDrop屬性設置為True - 拖動對象觸發DragDrop
private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
this.listBox1.DoDragDrop("Drag Data", DragDropEffects.Move);
}
- 拖到目標響應DragDrop
private void listBox2_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
//設置DragDrop效果
e.Effect = DragDropEffects.Move;
}
}
private void listBox2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
//執行DragDrop邏輯
this.listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
this.listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));
}
控件拖拽的參數
public DragDropEffects DoDragDrop ( Object data,DragDropEffects allowedEffects)
- data:戶所要拖動的數據內容。必須將所要拖動的內容傳入到這個方法的第一個參數位置。并不是必須得,比如在不同應用間傳遞數據時,可以借由剪切板。
控件拖拽的特效
控件拖拽的特效由DragDropEffects枚舉來指定。
- DragDropEffects說明
成員名稱 | 說明 |
---|---|
All | Copy、Move 和 Scroll 效果的組合 |
Copy | 將拖動源中的數據復制到放置目標,圖標為一個框右上角帶+ |
Link | 將拖動源中的數據鏈接到放置目標,圖標為數據快捷圖標 |
Move | 將拖動源的數據移動到放置目標,圖標為一個框 |
None | 放置目標不接受該數據,圖標為禁止標識 |
Scroll | 拖動時,如果有滾動條目,可以滾動目標,以定位在目標中當前不可見的某個放置位置 |
[Demo]
-
界面
-
功能
實現文件的拖拽以及應用程序之間的拖拽。