2012-04-19 2 views
4

나는 인터넷을 광범위하게 검색하여 이와 같은 많은 질문을 보았지만 실제 답변을 보지 못했습니다.서식있는 텍스트 상자 컨트롤에서 현재 스크롤 위치를 가져 옵니까?

텍스트가 많은 서식있는 텍스트 상자 컨트롤이 있습니다. 이 컨트롤에는 몇 가지 법적 정보가 있습니다. 기본적으로 "수락"버튼은 사용할 수 없습니다. v- 스크롤 막대의 위치가 아래쪽에 있으면 스크롤 이벤트를 감지하고 싶습니다. 맨 아래에 있으면 버튼을 활성화하십시오.

현재 v- 스크롤 막대 위치를 어떻게 감지합니까?

감사합니다!

편집 내가 윈폼 (닷넷 4.0)

+0

윈폼이나 WPF? –

+0

WinForms, .net 4.0 사용 –

+2

태그에 넣는 것이 가장 좋습니다. –

답변

12

이 기능을 확인 . 이 클래스는 RichTextBox를 상속 받아 스크롤 위치를 결정하기 위해 몇 개의 핀을 사용합니다. 사용자가 스크롤 바를 사용하여 스크롤하거나 키보드를 사용할 경우 실행되는 이벤트 ScrolledToBottom을 추가합니다.

public class RTFScrolledBottom : RichTextBox { 
    public event EventHandler ScrolledToBottom; 

    private const int WM_VSCROLL = 0x115; 
    private const int WM_MOUSEWHEEL = 0x20A; 
    private const int WM_USER = 0x400; 
    private const int SB_VERT = 1; 
    private const int EM_SETSCROLLPOS = WM_USER + 222; 
    private const int EM_GETSCROLLPOS = WM_USER + 221; 

    [DllImport("user32.dll")] 
    private static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos); 

    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, ref Point lParam); 

    public bool IsAtMaxScroll() { 
    int minScroll; 
    int maxScroll; 
    GetScrollRange(this.Handle, SB_VERT, out minScroll, out maxScroll); 
    Point rtfPoint = Point.Empty; 
    SendMessage(this.Handle, EM_GETSCROLLPOS, 0, ref rtfPoint); 

    return (rtfPoint.Y + this.ClientSize.Height >= maxScroll); 
    } 

    protected virtual void OnScrolledToBottom(EventArgs e) { 
    if (ScrolledToBottom != null) 
     ScrolledToBottom(this, e); 
    } 

    protected override void OnKeyUp(KeyEventArgs e) { 
    if (IsAtMaxScroll()) 
     OnScrolledToBottom(EventArgs.Empty); 

    base.OnKeyUp(e); 
    } 

    protected override void WndProc(ref Message m) { 
    if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL) { 
     if (IsAtMaxScroll()) 
     OnScrolledToBottom(EventArgs.Empty); 
    } 

    base.WndProc(ref m); 
    } 

} 

이이 익숙해 질 수있는 방법을 다음입니다 :

public Form1() { 
    InitializeComponent(); 
    rtfScrolledBottom1.ScrolledToBottom += rtfScrolledBottom1_ScrolledToBottom; 
} 

private void rtfScrolledBottom1_ScrolledToBottom(object sender, EventArgs e) { 
    acceptButton.Enabled = true; 
} 

는 필요에 따라 조정할.

+0

감사합니다. –

+0

사용자가 스크롤 막대를 잡고 이동하는 동안 스크롤 위치가 업데이트되지 않습니다. 마우스 버튼을 놓은 후에 만. –

+0

'this.ClientSize.Height'를 스크롤 위치에 추가해야하는 이유를 설명해 주시겠습니까? 스크롤이 맨 아래에 있더라도 왜 스크롤 위치가 'maxScroll'과 같지 않습니까? –

2

다음 작품 잘 내 솔루션 중 하나를

Point P = new Point(rtbDocument.Width, rtbDocument.Height); 
int CharIndex = rtbDocument.GetCharIndexFromPosition(P); 

if (rtbDocument.TextLength - 1 == CharIndex) 
{ 
    btnAccept.Enabled = true; 
} 
관련 문제