2011-05-17 134 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