RichTextBox ScrollToCaret的结果不一致

问题描述 投票:7回答:4

我正在使用C#中的RichTextBox。它存在于TabPage上。选择TabPage时,我的目标是填充RichTextBox,并滚动到结尾。我已经尝试了针对这个常见问题的解决方案的微小变化,主要问题是:

MyRichTextBox.Select(MyRichTextBox.Text.Length, 0);  
MyRichTextBox.ScrollToCaret();  

要么:

MyRichTextBox.SelectionStart = MyRichTextBox.Text.Length;  
MyRichTextBox.ScrollToCaret();  

这产生了不一致的结果,尽管是以可预测的方式。它将在滚动到底部之间交替,并在底部之间滚动一条线。分别说明(抱歉链接,新用户,所以我无法发布图像): Successfully scrolled to bottom Scrolled to one line short of the bottom 我很惊讶没有发现通过我的搜索没有提到这种行为,并决定询问这里是否有人遇到过这种情况,和/或有一个解决方案。如果归结为它,我想我可以选择与itsmatt's answer一致的东西。

c# scroll richtextbox
4个回答
27
投票

我对ScrollToCaret做了一些进一步的实验,并且每次都不会在同一个位置结束。由于我的目标仅限于一直向下滚动,因此它很适合将WM_VSCROLL消息(277或0x115)发送到控件,其中wParam为SB_PAGEBOTTOM(7)。这一直一直滚动到最底部,完全像我需要的那样:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
private const int WM_VSCROLL = 277;
private const int SB_PAGEBOTTOM = 7;

public static void ScrollToBottom(RichTextBox MyRichTextBox)
{
    SendMessage(MyRichTextBox.Handle, WM_VSCROLL, (IntPtr)SB_PAGEBOTTOM, IntPtr.Zero);
}

1
投票

改变它以适合您的工作代码..

String gotoCaret = "Something on this line.";
int position = textBox.Text.IndexOf(gotoCaret);
MyRichTextBox.SelectionStart = position;
MyRichTextBox.ScrollToCaret();

1
投票

我遇到了同样的错误(现在是7岁以上),ScrollToCaret()在最后一行和几乎最后一行之间交替跳转。避免使用非托管代码的另一个解决方案是两次调用ScrollToCaret()。

RichBox.Select(TheLocationYouWantToScrollTo, 0);
RichBox.ScrollToCaret();
RichBox.ScrollToCaret();

这种方法有时会产生一点点屏幕闪烁(不错,但不是超级平滑),因为它滚动到一行然后滚动到另一行。您可能会尝试以这种方式解决轻微的闪烁,但它不起作用:

RichBox.SuspendLayout(); // I won't actually suspend this layout
RichBox.Select(TheLocationYouWantToScrollTo, 0);
RichBox.ScrollToCaret();
RichBox.ScrollToCaret();
RichBox.ResumeLayout();

您还可以通过确保新位置位于新行上来减少闪烁:

RichBox.Select(TheLocationYouWantToScrollTo, 0)
if (RichBox.Transcription.GetFirstCharIndexOfCurrentLine() != ThePriorCharIndexOfCurrentLine)
{
   RichBox.ScrollToCaret();
   RichBox.ScrollToCaret(); 
}

当我们处于新线时,仅通过滚动来减少闪烁。


0
投票

我有同样的问题,我猜一个RTB几乎完全由Windows消息管理,所以它听起来有点像兔子沃伦。因此,我不知道交替输出的原因(但它有一点虫味)。我关注这个RTB.Scrolltocaret闪烁输出但是在VB程序中。对您的大胆解决方案的赞美:它完美无缺。

如果有人在编程环境中遇到这种异常,这里是VB代码

Imports System.Runtime.InteropServices
Public Class Form
<DllImport("user32.dll",CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage( _
ByVal hWnd As IntPtr, _
ByVal wMsg As Integer, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As Integer
End Function
Const WM_SCROLL = 277
Const SB_PAGEBOTTOM = 7
Sub ScrollToBottom(ByVal RTBName As RichTextBox)
   SendMessage(RTBName.Handle, _
               WM_SCROLL, _
               SB_PAGEBOTTOM, _
               IntPtr.Zero)
End Sub 'then call ScrollToBottom instead of ScrollToCaret
© www.soinside.com 2019 - 2024. All rights reserved.