如何同步在2树视图使用滑块滚动 [英] how do i sync scrolling in 2 treeviews using the slider
问题描述
我使用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屋!