2011-05-17 136 views

回答

9

當您在樹視圖控件中實現拖放時,您需要支持某種類型的自動滾動功能。例如,當您從可見樹節點拖動項目,並且目標樹節點位於樹視圖的當前視圖之外時,控件應根據鼠標的方向自動向上或向下滾動。

Windows窗體Treeview控件不包含內置功能來完成此操作。但是,自己實現這一點相當容易。

第1步:讓您的TreeView拖放代碼工作

確保你的TreeView拖放代碼工作正常不自動滾動。有關如何在樹視圖中實現拖放的更多信息,請參閱此文件夾中的主題。

第2步:SendMessage函數

添加定義爲了告訴樹形視圖向上或向下滾動,你需要調用Windows API的SendMessage()函數。

// Make sure you have the correct using clause to see DllImport: 
// using System.Runtime.InteropServices; 
[DllImport("user32.dll")] 
    private static extern int SendMessage (IntPtr hWnd, int wMsg, int wParam, 
     int lParam); 

第3步:要做到這一點,你的類的頂部添加以下代碼勾入DragScroll事件

在DragScroll情況下,確定鼠標光標是相對於頂部和treeview控件的底部。然後調用SendMessage作爲apporpriate滾動。

// Implement an "autoscroll" routine for drag 
// and drop. If the drag cursor moves to the bottom 
// or top of the treeview, call the Windows API 
// SendMessage function to scroll up or down automatically. 
private void DragScroll (
    object sender, 
    DragEventArgs e) 
{ 
    // Set a constant to define the autoscroll region 
    const Single scrollRegion = 20; 

    // See where the cursor is 
    Point pt = TreeView1.PointToClient(Cursor.Position); 

    // See if we need to scroll up or down 
    if ((pt.Y + scrollRegion) > TreeView1.Height) 
    { 
     // Call the API to scroll down 
     SendMessage(TreeView1.Handle, (int)277, (int)1, 0); 
    } 
    else if (pt.Y < (TreeView1.Top + scrollRegion)) 
    { 
     // Call thje API to scroll up 
     SendMessage(TreeView1.Handle, (int)277, (int)0, 0); 
} 

摘自here

+0

優秀的職位! – Pacman 2011-05-17 18:11:36

+0

也許把'(TreeView1.Top + scrollRegion)'改成'(scrollRegion)'。在我看來,你不需要最高價值。首先,我嘗試添加TreeView1.Top(樹形視圖位於表單的底部),並在樹視圖中間添加滾動過程startet。所以我刪除了TreeView1.Top和我的樹視圖頂部的滾動開始。 – daniel 2012-02-15 09:58:09

+0

@shaahin,你可以發佈實際的winapi宏定義嗎? 我知道277是WM_VSCROLL,但我無法理解頭文件中的1和0。 – 2012-03-06 17:45:16

20

與上述非常相似,但沒有「頂級」錯誤並且在更大的項目中使用更簡單一些。

這個類添加到您的項目:

public static class NativeMethods 
{ 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

    public static void Scroll(this Control control) 
    { 
     var pt = control.PointToClient(Cursor.Position); 

     if ((pt.Y + 20) > control.Height) 
     { 
      // scroll down 
      SendMessage(control.Handle, 277, (IntPtr) 1, (IntPtr) 0); 
     } 
     else if (pt.Y < 20) 
     { 
      // scroll up 
      SendMessage(control.Handle, 277, (IntPtr) 0, (IntPtr) 0); 
     } 
    } 
} 

然後只需訂閱您的TreeView的DragOver事件(或要滾動而拖/丟棄啓用的任何其它控制/自定義控制),並調用滾動( ) 方法。

private void treeView_DragOver(object sender, DragEventArgs e) 
    { 
     treeView.Scroll(); 
    } 
+0

@Vedran這太棒了!但有沒有辦法讓電視滾動慢一點?我的似乎要快一點...? – MaxOvrdrv 2015-12-18 18:35:55