在做C#的WinForm開發的時候,有時需要使用者往指定的控制項中拖進檔案或者檔案夾。然後根據使用者拖進來的檔案或者檔案夾擷取其資訊並進行下一步操作。
網路中百度或者Google一下有很多相關文章進行說明,不過很多都是不得的,或者說沒有達到你所要的要求。剛好我這陣子弄一個東西需要到這樣的操作,下面我們來探討一下具體怎麼實現。
實際上任何包含有AllowDrop屬性的控制項都會有對應的四個拖動事件:DragDrop、DragEnter、DragLeave和DragOver。
相關說明:
DragDrop:拖放操作完成時發生。
DragEnter:在將對象拖入控制項的邊界時發生。
DragLeave:在將對象拖出控制項的邊界時發生。
DragOver:在將對象拖到控制項的邊界上發生。
如果你不想在一拖動東西剛剛進到控制項就觸發事件,而是希望等你放開滑鼠之後再觸發。那你就不能使用DragEnter事件,而應該使用DragDrop事件。
事實是:設定控制項的AllowDrop屬性為true之後,你雙擊控制項的DragDrop事件,進入到事件的代碼區,你會發現不管你拖動任何東西到控制項中去,都不會觸發DragDrop事件。
同時,如果你雙擊控制項的DragEnter事件,你拖動任何東西進去都會觸發該事件。你設斷點跟蹤一下即可發現一下情況:
你如果在DragEnter事件中更改DragEventArgs委託類型的參數e.Effect屬性,比如,在DragEnter事件中寫:
private void listView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.None;//(使用DragEventArgs型別參數的Effect屬性來設定所允許的置放操作。只要不是:e.Effect = DragDropEffects. None,其它都可以,這裡的目的是觸發DragDrop事件。)
}
此時你往控制項中拖動任何東西的時候都會觸發DragDrop事件。這個時候你就可以把東西拖動進控制項後,等你放開滑鼠了才進行你想要的操作。這裡涉及到.Net事件模型的運行機制。你可以通過更改同一個對象的(即控制項,這裡的例子用到的是ListView控制項)DragEventArgs委託型別參數來實現觸發同一個對象的其他事件。
以下是我寫的小常式,當拖動進來的是檔案(或者檔案夾)的時候,就彈出訊息框,訊息框內容顯示拖動進來的檔案(或者檔案夾)的路徑資訊。當拖動進來的是常值內容的時候,label2控制項就顯示常值內容資訊。
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Link;
}
else if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effect = DragDropEffects.Copy;
}
}
private void listView1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string str = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
MessageBox.Show(str, "提示資訊", MessageBoxButtons.OK);
}
else if (e.Data.GetDataPresent(DataFormats.Text))
{
label2.Text = (e.Data.GetData(DataFormats.Text)).ToString();
}
}