TreeView Autoscroll докато плъзгате

Winforms TreeView, искам да превъртя нагоре/надолу, когато потребителят плъзга и елемент.


person Pacman    schedule 17.05.2011    source източник


Отговори (2)


Когато прилагате плъзгане и пускане в контрола за дървовиден изглед, трябва да поддържате някакъв тип функционалност за автоматично превъртане. Например, когато плъзнете елемент от видим дървовиден възел и целевият възел на дървото е извън текущия изглед на дървовидния изглед, контролата трябва автоматично да превърта нагоре или надолу в зависимост от посоката на мишката.

Контролата Treeview на Windows Forms не включва вградена функционалност за постигане на това. Въпреки това е доста лесно да приложите това сами.

Стъпка 1: Накарайте кода за плъзгане и пускане на вашия дървовиден изглед да работи

Уверете се, че вашият код за плъзгане и пускане на дървовиден изглед работи правилно без автоматично превъртане. Вижте темите в тази папка за повече информация как да приложите плъзгане и пускане в дървовиден изглед.

Стъпка 2: Добавете дефиниция за функцията SendMessage

За да кажете на дървовидния изглед да превърта нагоре или надолу, трябва да извикате функцията SendMessage() на Windows API. За да направите това, добавете следния код в горната част на вашия клас:

// 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 определете къде е курсорът на мишката спрямо горната и долната част на контролата за дървовиден изглед. След това извикайте SendMessage, за да превъртите, както е подходящо.

// 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);
}

Взето от тук.

person Shahin    schedule 17.05.2011
comment
Може би сменете (TreeView1.Top + scrollRegion) на (scrollRegion). Според мен не се нуждаете от най-високата стойност. Първо се опитах да добавя TreeView1.Top (дървовидният изглед е в долната част на моя формуляр) и процесът на превъртане стартира в средата на дървовидния изглед. Така че премахнах TreeView1.Top и превъртането започна в горната част на моя дървовиден изглед. - person daniel; 15.02.2012
comment
@shaahin, бихте ли публикували действителните макро дефиниции на winapi? Знам, че 277 е WM_VSCROLL, но не мога да разбера смисъла на 1 и 0 от заглавните файлове. - person Jonathan Henson; 06.03.2012
comment
Благодаря! Свързах го към събитието DragOver, защото няма такова събитие като DragScroll - person Couitchy; 10.06.2014

До голяма степен същото като горното, но без този „топ“ бъг и малко по-прост за използване в по-големи проекти.

Добавете този клас към вашия проект:

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);
        }
    }
}

След това просто се абонирайте за събитието DragOver на вашия дървовиден изглед (или всяка друга контрола/персонализирана контрола, чието превъртане искате да е активирано при плъзгане/пускане) и извикайте метода Scroll().

    private void treeView_DragOver(object sender, DragEventArgs e)
    {
        treeView.Scroll();
    }
person Vedran    schedule 27.06.2011
comment
@Ведран страхотно е! но има ли начин да направите превъртането на телевизора малко по-бавно? Моят май върви малко бързо... ? - person MaxOvrdrv; 18.12.2015