最近,我正在使用自定义GUI的表单项目。 (MetroFrameWork)它有自己的TextBox组件,但我更喜欢RichTextBox。问题是,如果我将其设置为可见,它将使用Windows旧版滚动条。我不想用这个。幸运的是框架有自己的ScrollBar组件和我想要的皮肤。我可以将RichTextBox设置为无滚动条(ScrollBars属性设置为NONE),并将独立的自定义滚动条停靠在RichTextBox的右侧。我没有找到任何好的解决方案如何将自定义滚动条控件导出或附加到我的遗留RichTextBox,就像它在RTB内置滚动条一样。所以我试着手动完成。填充RTB时,我可以计算自定义滚动条Minimum,Maximum,SmallChange,LargeChange属性,以便设置滚动条拇指大小。我实现了使用cathich自定义滚动条的滚动事件来模拟滚动方法,然后可以使用互操作服务(user32.dll)垂直滚动RTB的文本内容(只需要垂直滚动):
private void metroScrollBarRichTextBoxMain_Scroll(object sender, ScrollEventArgs e)
{
uint nPos = (uint)metroScrollBarRichTextBoxMain.Value * (uint)Math.Round((decimal)richTextBoxMain.Font.GetHeight(), 1, MidpointRounding.AwayFromZero);
uint wParam = (uint)WindowMessageConstants.ScrollBarCommands.SB_THUMBPOSITION | nPos << 16;
SendMessage(richTextBoxMain.Handle, WindowMessageConstants.WM_VSCROLL, (IntPtr)wParam, IntPtr.Zero);
}
所以当我们按住滚动条的拇指时滚动鼠标就可以了。但这里有捕获,我想使用RichTextBox其他abilites,如滚动文本内容与箭头键和鼠标滚轮。鼠标滚轮没问题,可以轻松实现。但是,如果用户使用键盘箭头滚动内容,我无法找到任何捕获事件的解决方案。它需要因为我必须将位置同步到我的自定义滚动条。当RTB在使用键盘箭头时向下或向上移动文本内容一行时,我找不到任何解决方案。当您使用鼠标进行选择并向RTB的上边缘或下边缘滑动时(它也会滚动文本) 在这种情况下会发生什么事件?它就像ScrollToCaret函数,但它不会触发任何事件。如果我将垂直滚动条设置为可见的其他方法,并且&#34;隐藏&#34;在我的自定义滚动条后面。在这种情况下,我可以获得滚动位置以同步我的滚动条位置。但这很难看,必须有更好的方法。 我试图通过WndProc捕获是否有任何滚动效果:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WindowMessageConstants.WM_VSCROLL || m.Msg == WindowMessageConstants.WM_HSCROLL ||
m.Msg == WindowMessageConstants.WM_MOUSEWHEEL)
{
...do something here
}
}
但这只是在滚动或滚轮滚动发生时。当您使用键盘箭头滚动时不会。
你们能告诉我一个怎么做到这一点的方法吗?或许我的方法完全错误,也许有办法,我可以从我的自定义滚动条控件中导出/继承旧RTB控件,这样我就可以将自定义滚动条完全附加到richtextbox WHILE RTB的ScrollBars属性设置为NONE。 (因此内置滚动条不可见)
对不起我的长篇解释,我几天都在搜索解决方案但没有成功......