如何同步在2树视图使用滑块滚动 [英] how do i sync scrolling in 2 treeviews using the slider

查看:217
本文介绍了如何同步在2树视图使用滑块滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用VS2010(C#)和一个WinForms应用程序,我有2侧树视图方面,我已经找到了如何使用滚动条上的上/下按钮同步滚动但是当我使用滑块它不移动其他树视图。我采取的作品列表视图的例子,但相同的代码不会为树视图工作。

I am using VS2010 (c#) and a winforms application, I have 2 treeviews side by side, I have figured out how to sync the scrolling using the up/down buttons on the scrollbar but when i use the slider it does not move the other treeview. I have taken a listview example that works, but the same code does not work for treeviews.

到目前为止,我已经在主要形式

So far i have, in the main form

    [DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

    private void myListBox1_Scroll(ref Message m)
    {
        SendMessage(myListBox2.Handle, (uint)m.Msg, (uint)m.WParam, (uint)m.LParam);            
    }



我创建了一个控制

I have created a control

public partial class MyTreeView : TreeView
{
    public MyTreeView()
    {
        InitializeComponent();
    }

    public event ScrollEventHandler Scroll;
    public delegate void ScrollEventHandler(ref Message m);


    private const int WM_VSCROLL = 0x115;

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        if (m.Msg == WM_VSCROLL)
            if (Scroll != null)
            {
                Scroll(ref m);
            }

        base.WndProc(ref m);
    }

}



这是我的加两个到形成。

which i add two of to the form.

我可以使用相同的代码有listivew控制树形视图,如果你拖动滑块,将工作,但在相反它只用上下按钮的工作原理。

I can use the same code to have a listivew control the treeview and that will work if you drag the slider, but in reverse it only works with the up down buttons.

任何建议,将不胜感激。

Any suggestions would be much appreciated

推荐答案

而不是使用SendMessage函数并标记您的DLL为不安全的,你可以使用 GetScrollPos SetScrollPos 从user32.dll中的功能。

Rather than use SendMessage and mark your DLL as unsafe you can use the GetScrollPos and SetScrollPos functions from user32.dll.

我包裹代码成你MyTreeView类,所以它很好地封装。

I've wrapped the code up into your MyTreeView class so it's nicely encapsulated.

您只需要调用 AddLinkedTreeView 方法,像这样:

You just need to call the AddLinkedTreeView method like so:

treeView1.AddLinkedTreeView(treeView2);

下面是为MyTreeView类的源代码。

Here's the source for the MyTreeView class.

public partial class MyTreeView : TreeView
{
    public MyTreeView() : base()
    {
    }

    private List<MyTreeView> linkedTreeViews = new List<MyTreeView>();

    /// <summary>
    /// Links the specified tree view to this tree view.  Whenever either treeview
    /// scrolls, the other will scroll too.
    /// </summary>
    /// <param name="treeView">The TreeView to link.</param>
    public void AddLinkedTreeView(MyTreeView treeView)
    {
        if (treeView == this)
            throw new ArgumentException("Cannot link a TreeView to itself!", "treeView");

        if (!linkedTreeViews.Contains(treeView))
        {
            //add the treeview to our list of linked treeviews
            linkedTreeViews.Add(treeView);
            //add this to the treeview's list of linked treeviews
            treeView.AddLinkedTreeView(this);

            //make sure the TreeView is linked to all of the other TreeViews that this TreeView is linked to
            for (int i = 0; i < linkedTreeViews.Count; i++)
            {
                //get the linked treeview
                var linkedTreeView = linkedTreeViews[i];
                //link the treeviews together
                if (linkedTreeView != treeView)
                    linkedTreeView.AddLinkedTreeView(treeView);
            }
        }
    }

    /// <summary>
    /// Sets the destination's scroll positions to that of the source.
    /// </summary>
    /// <param name="source">The source of the scroll positions.</param>
    /// <param name="dest">The destinations to set the scroll positions for.</param>
    private void SetScrollPositions(MyTreeView source, MyTreeView dest)
    {
        //get the scroll positions of the source
        int horizontal = User32.GetScrollPos(source.Handle, Orientation.Horizontal);
        int vertical = User32.GetScrollPos(source.Handle, Orientation.Vertical);
        //set the scroll positions of the destination
        User32.SetScrollPos(dest.Handle, Orientation.Horizontal, horizontal, true);
        User32.SetScrollPos(dest.Handle, Orientation.Vertical, vertical, true);
    }

    protected override void WndProc(ref Message m)
    {
        //process the message
        base.WndProc(ref m);

        //pass scroll messages onto any linked views
        if (m.Msg == User32.WM_VSCROLL || m.Msg == User32.WM_MOUSEWHEEL)
        {
            foreach (var linkedTreeView in linkedTreeViews)
            {
                //set the scroll positions of the linked tree view
                SetScrollPositions(this, linkedTreeView);
                //copy the windows message
                Message copy = new Message
                {
                    HWnd = linkedTreeView.Handle,
                    LParam = m.LParam,
                    Msg = m.Msg,
                    Result = m.Result,
                    WParam = m.WParam
                };
                //pass the message onto the linked tree view
                linkedTreeView.RecieveWndProc(ref copy);
            }                               
        }
    }

    /// <summary>
    /// Recieves a WndProc message without passing it onto any linked treeviews.  This is useful to avoid infinite loops.
    /// </summary>
    /// <param name="m">The windows message.</param>
    private void RecieveWndProc(ref Message m)
    {
        base.WndProc(ref m);
    }

    /// <summary>
    /// Imported functions from the User32.dll
    /// </summary>
    private class User32
    {
        public const int WM_VSCROLL = 0x115;
        public const int WM_MOUSEWHEEL = 0x020A;  

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetScrollPos(IntPtr hWnd, System.Windows.Forms.Orientation nBar);

        [DllImport("user32.dll")]
        public static extern int SetScrollPos(IntPtr hWnd, System.Windows.Forms.Orientation nBar, int nPos, bool bRedraw);
    }
}



修改:新增转发的WM_MOUSEWHEEL消息作为每MinnesotaFat的建议。

Edit: Added forwarding of the WM_MOUSEWHEEL message as per MinnesotaFat's suggestion.

这篇关于如何同步在2树视图使用滑块滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆