2015-04-21 2 views

ответ

1

Это должен быть RichTextBox, чтобы вы могли использовать его свойство SelectionProtected, чтобы гарантировать, что пользователь не может изменить текст. Он не имеет события Scroll, но может быть добавлен путем переопределения WndProc() и обнаружения сообщения WM_VSCROLL. Проверка того, что последняя строка видна, как @TaW, не является надежной, если для свойства WordWrap установлено значение False. Легче просто проверить состояние полосы прокрутки.

Добавить новый класс в ваш проект и вставить код, показанный ниже. Компиляция. Отбросьте новый элемент управления сверху панели инструментов на свою форму. Подпишитесь на событие LicenseViewed и установите флажок «Включено» в значение true. Я был бы упущен, если бы не заметил, что только юристы думают, что это хорошая идея, пользователи находят такие текстовые поля повсеместно раздражающими и ненавидят их со страстью. У вас есть только один шанс создать хорошее первое впечатление.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class LicenseBox : RichTextBox { 
    public event EventHandler LicenseViewed; 

    public override string Text { 
     get { return base.Text; } 
     set { base.Text = value; textChanged(); } 
    } 

    public new string Rtf { 
     get { return base.Rtf; } 
     set { base.Rtf = value; textChanged(); } 
    } 

    private bool eventFired; 

    private void textChanged() { 
     this.SelectAll(); 
     this.SelectionProtected = true; 
     this.SelectionStart = this.SelectionLength = 0; 
     eventFired = false; 
     checkScrollbar(); 
    } 

    private void checkScrollbar() { 
     if (eventFired || !this.IsHandleCreated) return; 
     var pos = new ScrollInfo(); 
     pos.cbSize = Marshal.SizeOf(pos); 
     pos.fMask = 7; 
     if (!GetScrollInfo(this.Handle, SB_VERT, ref pos)) return; 
     if (pos.nPos >= pos.nMax - pos.nPage) { 
      if (LicenseViewed != null) LicenseViewed(this, EventArgs.Empty); 
      eventFired = true; 
     } 
    } 

    protected override void WndProc(ref Message m) { 
     base.WndProc(ref m); 
     if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL) checkScrollbar(); 
    } 

    // Pinvoke 
    private const int WM_VSCROLL = 0x115; 
    private const int WM_MOUSEWHEEL = 0x20A; 
    private const int SB_VERT = 1; 
    private struct ScrollInfo { 
     public int cbSize, fMask, nMin, nMax, nPage, nPos, nTrackPos; 
    } 
    [DllImport("user32.dll", SetLastError = true)] 
    private static extern bool GetScrollInfo(IntPtr hwnd, int bar, ref ScrollInfo pos); 

} 
+0

_This должен быть RichTextBox, чтобы вы могли использовать его свойство SelectionProtected, чтобы гарантировать, что пользователь не может изменить текст ._ - Было бы лучше, чем сделать TextBox только для чтения? – TaW

+0

Никто никогда не думает, что TextBox выглядит лучше с включенным. –

+0

Согласился на внешний вид, по крайней мере, если они не предлагают текст для редактирования. – TaW

0

Вот функция, которая говорит вам, если последняя строка видна:

bool LastLineVisible(TextBox textbox) 
{ 
    Point lowPoint = new Point(3, textbox.ClientSize.Height - 3); 
    int lastline = textbox.Lines.Count() - 1; 
    int charOnLastvisibleLine = textbox.GetCharIndexFromPosition(lowPoint); 
    int lastVisibleLine = textbox.GetLineFromCharIndex(charOnLastvisibleLine); 
    return lastVisibleLine >= lastline; 
} 

Вы все еще нужно определить само событие прокрутки. См. here о том, как определить прокрутку.

+0

Спасибо, я создал класс ScrollThumb, но как мне получить доступ к событиям? Я поставил точку останова в классе и, похоже, никогда не дошел до него. – KingC

+0

Вы изменили исходный TextBox как экземпляр класса ScrollThumb? (Или повторно добавьте объект ScrollThumb или измените 2 пятна в файле Designer.cs из TextBox на ScrollThumb!) – TaW

Смежные вопросы