Don*_*nut 16 .net c# scroll richtextbox winforms
在我的应用程序表单中,我有两个RichTextBox对象.它们将始终具有相同数量的文本行.我想"同步"这两者之间的垂直滚动,这样当用户在一个上改变垂直滚动位置时,另一个滚动相同的量.我该怎么做呢?
Don*_*nut 21
谢谢杰伊的回答; 经过一番搜索,我也找到了这里描述的方法.对于其他感兴趣的人,我将在下面概述.
首先,声明以下枚举:
public enum ScrollBarType : uint {
SbHorz = 0,
SbVert = 1,
SbCtl = 2,
SbBoth = 3
}
public enum Message : uint {
WM_VSCROLL = 0x0115
}
public enum ScrollBarCommands : uint {
SB_THUMBPOSITION = 4
}
Run Code Online (Sandbox Code Playgroud)
接下来,添加外部引用GetScrollPos和SendMessage.
[DllImport( "User32.dll" )]
public extern static int GetScrollPos( IntPtr hWnd, int nBar );
[DllImport( "User32.dll" )]
public extern static int SendMessage( IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam );
Run Code Online (Sandbox Code Playgroud)
最后,为VScroll适当的事件添加事件处理程序RichTextBox:
private void myRichTextBox1_VScroll( object sender, EventArgs e )
{
int nPos = GetScrollPos( richTextBox1.Handle, (int)ScrollBarType.SbVert );
nPos <<= 16;
uint wParam = (uint)ScrollBarCommands.SB_THUMBPOSITION | (uint)nPos;
SendMessage( richTextBox2.Handle, (int)Message.WM_VSCROLL, new IntPtr( wParam ), new IntPtr( 0 ) );
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,richTextBox2垂直滚动位置将与之同步richTextBox1.
Jay*_*ggs 15
我之前为一个小项目做过这个,这是我发现的简单解决方案.
通过继承RichTextBox创建一个新控件:
public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTextBox
{
public event vScrollEventHandler vScroll;
public delegate void vScrollEventHandler(System.Windows.Forms.Message message);
public const int WM_VSCROLL = 0x115;
protected override void WndProc(ref System.Windows.Forms.Message msg) {
if (msg.Msg == WM_VSCROLL) {
if (vScroll != null) {
vScroll(msg);
}
}
base.WndProc(ref msg);
}
public void PubWndProc(ref System.Windows.Forms.Message msg) {
base.WndProc(ref msg);
}
}
Run Code Online (Sandbox Code Playgroud)
将新控件添加到表单中,并为每个控件显式通知控件的其他实例其vScroll位置已更改.像这样的东西:
private void scrollSyncTxtBox1_vScroll(Message msg) {
msg.HWnd = scrollSyncTxtBox2.Handle;
scrollSyncTxtBox2.PubWndProc(ref msg);
}
Run Code Online (Sandbox Code Playgroud)
我认为如果所有"链接"控件没有相同数量的可显示行,则此代码会出现问题.
小智 5
[Windows 7 64 位安装上的 Visual Studio C# 2010 Express,v10.0.30319]
我使用了上面发布的 Donut 解决方案,但是在滚动到包含多行的 RichTextBoxes 末尾时发现了一个问题。
如果结果GetScrollPos()是>0x7FFFthen whennPos移位,则设置最高位。IntPtr使用结果wParam变量创建将失败并显示OverflowException. 您可以使用以下内容轻松测试(第二行将失败):
IntPtr ip = new IntPtr(0x7FFF0000);
IntPtr ip2 = new IntPtr(0x80000000);
Run Code Online (Sandbox Code Playgroud)
SendMessage()该用途的一个版本UIntPtr似乎是一种解决方案,但我无法让它发挥作用。所以,我使用了以下内容:
[DllImport("User32.dll")]
public extern static int SendMessage(IntPtr hWnd, uint msg, UInt32 wParam, UInt32 lParam);
Run Code Online (Sandbox Code Playgroud)
这应该很好0xffff,但在那之后会失败。我还没有经历过>0xffff来自的结果GetScrollPos(),并假设 User32.dll 不太可能有 64 位版本的SendCommand(),但是对于该问题的任何解决方案都将不胜感激。