最近我在一个带有自定义GUI的表单项目上 . (MetroFrameWork)它有自己的TextBox组件,但我更喜欢RichTextBox . 问题是,如果我将其设置为可见,它将使用Windows旧版滚动条 . 我不想用这个 . 幸运的是框架有自己的ScrollBar组件和我想要的皮肤 . 我可以将RichTextBox设置为无滚动条(ScrollBars属性设置为NONE)并将独立的自定义滚动条设置为停靠在RichTextBox的右侧 . 我没有找到任何好的解决方案如何将自定义滚动条控件导出或附加到我的遗留RichTextBox,就像它作为RTB内置滚动条一样行为 . 所以我试着手动完成 . 当填充RTB时,我可以计算我的自定义滚动条Minimum,Maximum,SmallChange,LargeChange属性,以便它可以设置滚动条拇指大小 . 我实现了使用cathich自定义滚动条的滚动事件模拟滚动方法然后可以垂直滚动RTB的文本内容(只需要垂直滚动)和互操作服务(user32.dll):

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函数,但它不会触发任何事件 . 如果我将垂直滚动条设置为可见,并在我的自定义滚动条后面“隐藏”,则采用其他方法 . 在这种情况下,我可以获得滚动位置以同步我的滚动条位置 . 但这很难看,必须有更好的方法 . 我尝试捕获是否通过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 . (因此内置滚动条不可见)

对不起我的长篇解释,我搜索了解决方案,到处都没有成功...