如何知道RichTextBox垂直滚动条是否达到最大值?

时间:2013-10-13 09:43:21

标签: c# .net vb.net winforms richtextbox

当使用richtextbox方法“ScrollToCaret”时,我需要知道滚动条是否到达顶部/底部边距。

这是因为当垂直滚动条完全滚动到底部时,如果我再次使用“ScrollToCaret”方法,那么它会在控件中产生一种奇怪的视觉效果,因为它尝试并重试向下滚动但是没有更多滚动,我无法理解richtextbox控件这种奇怪的逻辑。

我希望你能理解我,原谅我的英语。

PS:我正在使用默认的richtextbox垂直滚动条。

2 个答案:

答案 0 :(得分:4)

你必须处理一点Win32。我们需要win32方法GetScrollInfo。有了它,我们可以获得最大范围,拇指的当前位置和Page大小(thumb大小)。所以我们有这个公式:

最大排名=最大排名 - 拇指大小

现在是你的代码:

//Must add using System.Runtime.InteropServices;
//We can define some extension method for this purpose
public static class RichTextBoxExtension {
    [DllImport("user32")]
    private static extern int GetScrollInfo(IntPtr hwnd, int nBar, 
                                            ref SCROLLINFO scrollInfo);

    public struct SCROLLINFO {
      public int cbSize;
      public int fMask;
      public int min;
      public int max;
      public int nPage;
      public int nPos;
      public int nTrackPos;
    }
    public static bool ReachedBottom(this RichTextBox rtb){
       SCROLLINFO scrollInfo = new SCROLLINFO();
       scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
       //SIF_RANGE = 0x1, SIF_TRACKPOS = 0x10,  SIF_PAGE= 0x2
       scrollInfo.fMask = 0x10 | 0x1 | 0x2;
       GetScrollInfo(rtb.Handle, 1, ref scrollInfo);//nBar = 1 -> VScrollbar
       return scrollInfo.max == scrollInfo.nTrackPos + scrollInfo.nPage;
    }
}
//Usage:
if(!yourRichTextBox.ReachedBottom()){
   yourRichTextBox.ScrollToCaret();
   //...
}

答案 1 :(得分:1)

这是@King King版本我已将其翻译成VB.NET并添加了更多功能,我认为所有这些功能都正常:

Public Class ScrollBarInfo

<System.Runtime.InteropServices.DllImport("user32")> _
Private Shared Function GetScrollInfo(hwnd As IntPtr, nBar As Integer, ByRef scrollInfo As SCROLLINFO) As Integer
End Function

Private Shared scrollInf As New SCROLLINFO()

Private Structure SCROLLINFO
    Public cbSize As Integer
    Public fMask As Integer
    Public min As Integer
    Public max As Integer
    Public nPage As Integer
    Public nPos As Integer
    Public nTrackPos As Integer
End Structure

Private Shared Sub Get_ScrollInfo(control As Control)
    scrollInf = New SCROLLINFO()
    scrollInf.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(scrollInf)
    scrollInf.fMask = &H10 Or &H1 Or &H2
    GetScrollInfo(control.Handle, 1, scrollInf)
End Sub

Public Shared Function ReachedBottom(control As Control) As Boolean
    Get_ScrollInfo(control)
    Return scrollInf.max = scrollInf.nTrackPos + scrollInf.nPage
End Function

Public Shared Function ReachedTop(control As Control) As Boolean
    Get_ScrollInfo(control)
    Return scrollInf.nTrackPos < 0
End Function

Public Shared Function IsAtBottom(control As Control) As Boolean
    Get_ScrollInfo(control)
    Return scrollInf.max = (scrollInf.nTrackPos + scrollInf.nPage) - 1
End Function

Public Shared Function IsAtTop(control As Control) As Boolean
    Get_ScrollInfo(control)
    Return scrollInf.nTrackPos = 0
End Function

End Class