2014-10-04 48 views
2

在WinForms和其他應用程序(例如Windows記事本)中,可以拖放(例如文件)到整個窗口中 - 這包括標題欄和窗口邊框。WPF:將文件拖放到整個窗口(包括標題欄和窗口邊框)

在WPF中,您只能將文件拖動到窗口畫布中 - 嘗試將其拖到標題欄或窗口邊框上,導致「否」遊標。

enter image description here

我怎樣才能讓一個普通的WPF窗口(SingleBorderWindow WindowStyle等)接受拖放到整個窗口?

回答

3

不同之處在於,當您設置AllowDrop =「true」時,WPF不會調用操作系統DragAcceptFiles API。 DragAcceptFiles將整個窗口註冊爲放置目標。

您需要安裝並有一個小窗口過程來處理放置消息。

這是我做的一個小測試程序,允許WPF窗口在任何地方接受放置。

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    const int WM_DROPFILES = 0x233; 

    [DllImport("shell32.dll")] 
    static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept); 

    [DllImport("shell32.dll")] 
    static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder filename, uint cch); 

    [DllImport("shell32.dll")] 
    static extern void DragFinish(IntPtr hDrop); 


    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 

     var helper = new WindowInteropHelper(this); 
     var hwnd = helper.Handle; 

     HwndSource source = PresentationSource.FromVisual(this) as HwndSource; 
     source.AddHook(WndProc); 

     DragAcceptFiles(hwnd, true); 
    } 

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_DROPFILES) 
     { 
      handled = true; 
      return HandleDropFiles(wParam); 
     } 

     return IntPtr.Zero; 
    } 

    private IntPtr HandleDropFiles(IntPtr hDrop) 
    { 
     this.info.Text = "Dropped!"; 

     const int MAX_PATH = 260; 

     var count = DragQueryFile(hDrop, 0xFFFFFFFF, null, 0); 

     for (uint i = 0; i < count; i++) 
     { 
      int size = (int) DragQueryFile(hDrop, i, null, 0); 

      var filename = new StringBuilder(size + 1); 
      DragQueryFile(hDrop, i, filename, MAX_PATH); 

      Debug.WriteLine("Dropped: " + filename.ToString()); 
     } 

     DragFinish(hDrop); 

     return IntPtr.Zero; 
    } 
} 
+0

很好用!有什麼方法可以設置拖動效果(光標)並獲得DragEnter和DragLeave事件的等價物嗎? – 2014-10-05 02:10:59

+1

要做到這一點,我認爲你需要完全轉向使用OLE拖放實現IDropTarget。這篇文章有很多我認爲:http://www.ookii.org/Blog/opening_files_via_idroptarget_in_net – jschroedl 2014-10-05 02:25:07