2

さて、DragDropManagerで次のように設定しました。

DragDropEffects.Scroll

許容される効果としてですが、何らかの理由で正しく機能していません。スクロールしようとすると、まだまったくスクロールしていません。誰かがこれについて私にきちんと説明してもらえますか?

カテゴリをドラッグしながらこれを使用しようとしています。

私はMSDNをチェックしましたが、機能が実際に何をするのか、そしてそれをどのように使用するのかについては本当に情報がありません。

この質問がばかげている場合は申し訳ありませんが、誰かが私を助けてくれることを願っています。

4

2 に答える 2

1

ここで2つの解決策を見つけることができます。1つはを使用してSendMessageおり、もう1つは純粋な.NETコードです。
http://www.dotnet247.com/247reference/msgs/16/81341.aspx
サイトがダウンしているようです。アーカイブされたページはここにあります

関連するWindowsメッセージコードはここで説明されています:
ListViewonScrollイベント

結果のコードは以下のとおりです。ただし、その点では、垂直スクロールバーと水平スクロールバーの存在を検出し、それに応じて下部と右側のスクロールトリガー領域を調整する機能が必要です。

private void treeView_DragOver(object sender, DragEventArgs e)
{
    TreeView senderTree = sender as TreeView;

    TreeNode destinationNode;
    TreeNode newNode = GetDragTreeNode(out destinationNode, sender, e);

    if (newNode == null)
    {
        e.Effect = DragDropEffects.None;
        return;
    }

    int scrollDetectRangeU = 10;
    int scrollDetectRangeL = 10;
    int scrollDetectRangeB = 10 + 20;
    int scrollDetectRangeR = 10 + 20;
    Point treeCoord = CoordToTreeCoord(senderTree, e);

    if (treeCoord.Y < scrollDetectRangeU 
        && (destinationNode == null || destinationNode.PrevVisibleNode != null))
    {
        SendMessage(senderTree.Handle, WindowsMessages.WM_VSCROLL, ScrollBarCommands.SB_LINEUP, IntPtr.Zero);    //scroll up
        Thread.Sleep(10);   //slow down the scrolling a bit
    }
    else if (treeCoord.Y >= senderTree.Height - scrollDetectRangeB 
        && (destinationNode == null || destinationNode.NextVisibleNode != null))
    {
        SendMessage(senderTree.Handle, WindowsMessages.WM_VSCROLL, ScrollBarCommands.SB_LINEDOWN, IntPtr.Zero);    //scroll down
        Thread.Sleep(10);   //slow down the scrolling a bit
    }

    if (treeCoord.X < scrollDetectRangeL)
    {
        SendMessage(senderTree.Handle, WindowsMessages.WM_HSCROLL, ScrollBarCommands.SB_LINELEFT, IntPtr.Zero);     //scroll left
    }
    else if (treeCoord.X >= senderTree.Width - scrollDetectRangeR)
    {
        SendMessage(senderTree.Handle, WindowsMessages.WM_HSCROLL, ScrollBarCommands.SB_LINERIGHT, IntPtr.Zero);     //scroll right
    }

}

private static TreeNode GetDragTreeNode(out TreeNode destinationNode, object sender, DragEventArgs e)
{
    TreeNode newNode = null;

    if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))  
    {
        newNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
    }

    if (newNode != null)
    {
        destinationNode = CoordToTreeNode(sender, e);    
    }
    else
    {
        destinationNode = null;
    }

    return newNode;
}

public static Point CoordToTreeCoord(object senderTree, DragEventArgs e)
{
    return CoordToTreeCoord(senderTree as TreeView, e.X, e.Y, true);
}

public static Point CoordToTreeCoord(TreeView senderTree, int x, int y, bool usePointToClient)
{
    Point pt = usePointToClient ? senderTree.PointToClient(new Point(x, y)) : new Point(x, y);

    return pt;
}

public static TreeNode CoordToTreeNode(object senderTree, DragEventArgs e)
{
    return CoordToTreeNode(senderTree as TreeView, e.X, e.Y, true);
}

public static TreeNode CoordToTreeNode(TreeView senderTree, int x, int y, bool usePointToClient)
{
    Point pt = CoordToTreeCoord(senderTree, x, y, usePointToClient);
    TreeNode destinationNode = senderTree.GetNodeAt(pt);

    return destinationNode;
}

[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, ScrollBarCommands wParam, IntPtr lParam);  

public enum ScrollBarCommands : int
{
    SB_LINEUP = 0,
    SB_LINELEFT = 0,
    SB_LINEDOWN = 1,
    SB_LINERIGHT = 1,
    SB_PAGEUP = 2,
    SB_PAGELEFT = 2,
    SB_PAGEDOWN = 3,
    SB_PAGERIGHT = 3,
    SB_THUMBPOSITION = 4,
    SB_THUMBTRACK = 5,
    SB_TOP = 6,
    SB_LEFT = 6,
    SB_BOTTOM = 7,
    SB_RIGHT = 7,
    SB_ENDSCROLL = 8
}

public static class WindowsMessages
{
    // Windows messages 
    public const int WM_PAINT = 0x000F;
    public const int WM_HSCROLL = 0x0114;
    public const int WM_VSCROLL = 0x0115;
    public const int WM_MOUSEWHEEL = 0x020A;
    public const int WM_KEYDOWN = 0x0100;
    public const int WM_LBUTTONUP = 0x0202;

    // ScrollBar types 
    public const int SB_HORZ = 0;
    public const int SB_VERT = 1;

    // ScrollBar interfaces 
    public const int SIF_TRACKPOS = 0x10;
    public const int SIF_RANGE = 0x01;
    public const int SIF_POS = 0x04;
    public const int SIF_PAGE = 0x02;
    public const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;

    // ListView messages 
    public const uint LVM_SCROLL = 0x1014;
    public const int LVM_FIRST = 0x1000;
    public const int LVM_SETGROUPINFO = (LVM_FIRST + 147);

}
于 2012-10-05T23:26:24.213 に答える
0

受け入れられた回答のリンクが壊れているように見えるので(再び?)、この問題を閲覧している人が、GitHubにリンクされたドラッグ中のスクロールを管理するデモコードがあるDrag&Dropをカバーするブログに興味があるのではないかと思いました。

mikeoncode.blogspot.co.uk

1つの側面は、ドラッグイベント引数によって提供されるXY座標が画面ベースであり、(それらを使用する場合)これらの座標を使用してスクロール可能な領域の位置を計算(および追跡)する必要があることです。それが確立されると、ドラッグカーソルの相対位置を測定し、カーソルが関連する境界に近づくとスクロールバーへの変更を開始するだけです。GitHubのソースコード

于 2016-05-12T13:59:34.050 に答える