2009-03-09 2 views
9

У меня есть окно ввода данных только для чтения, которое я реализовал с помощью элемента управления RichTextBox. Я хотел бы отключить автопрокрутку, которая происходит, когда пользователь нажимает элемент управления, чтобы пользователь мог выбрать конкретный журнал для операций копирования/вставки или что-то еще. Однако, как только пользователь нажимает на RichTextBox, он автоматически прокручивается вниз, что затрудняет это.Предотвращение автопрокрутки в RichTextBox

Кто-нибудь знает способ отменить это поведение?

Спасибо!

ответ

6

Вы можете взглянуть на делать что-то вроде этого:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
private static extern IntPtr LockWindowUpdate(IntPtr Handle); 

затем в методе, который присоединяет данные журнала (я сделать некоторые предположения здесь), вы можете сделать что-то вроде этого:

LockWindowUpdate(this.Handle); 
int pos = richTextBox1.SelectionStart; 
int len = richTextBox1.SelectionLength; 
richTextBox1.AppendText(yourText); 
richTextBox1.SelectionStart = pos; 
richTextBox1.SelectionLength = len; 
LockWindowUpdate(IntPtr.Zero); 

Я сделал небольшое тестовое приложение с таймером, который сделал добавление в richtextbox, и он остановил его от прокрутки, чтобы я мог выполнять выбор текста. Он имеет некоторые позиционные проблемы и не идеален, но, возможно, это поможет вам перейти к собственному решению.

Всего наилучшего!

11

Элемент управления RichTextBox автоматически прокручивается до текущего выделения, если выбор не скрыт. RichTextBox.AppendText(), помимо добавления текста, также изменяет текущий выбор и, таким образом, косвенно вызывает поведение «автопрокрутки». Обратите внимание, что если для RichTextBox.HideSelection установлено значение true, выбор будет скрыт, если элемент управления не находится в фокусе; это объясняет описанное вами поведение, когда автопрокрутка происходит только тогда, когда пользователь нажимает на элемент управления. (Тем самым давая ему фокус) Чтобы предотвратить это, вам нужно сделать следующее: при добавлении текста:

  1. резервного копирования первоначальный выбор
  2. Unfocus управления
  3. Скрыть выделение (через сообщение Windows)
  4. AppendText
  5. Восстановить первоначальный выбор выбор
  6. Unhide
  7. переориентировать управление

Возможно, вы также захотите проверить, находится ли выделение в конце текста и разрешить поведение автопрокрутки, если это так - это по существу эмулирует поведение окна вывода Visual Studio. Например: раствор

[System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam); 
    const int WM_USER = 0x400; 
    const int EM_HIDESELECTION = WM_USER + 63; 

    void OnAppend(string text) 
    { 
     bool focused = richTextBox1.Focused; 
     //backup initial selection 
     int selection = richTextBox1.SelectionStart; 
     int length = richTextBox1.SelectionLength; 
     //allow autoscroll if selection is at end of text 
     bool autoscroll = (selection==richTextBox1.Text.Length); 

     if (!autoscroll) 
     { 
      //shift focus from RichTextBox to some other control 
      if (focused) textBox1.Focus(); 
      //hide selection 
      SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 1, 0); 
     } 

     richTextBox1.AppendText(text); 

     if (!autoscroll) 
     { 
      //restore initial selection 
      richTextBox1.SelectionStart = selection; 
      richTextBox1.SelectionLength = length; 
      //unhide selection 
      SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 0, 0); 
      //restore focus to RichTextBox 
      if(focused) richTextBox1.Focus(); 
     } 
    } 
+0

Ваше решение работает как очарование! Я пробовал так много других подходов, чтобы предотвратить прокрутку RichTextBox после внесения изменений в форматирование, и это было единственное, что сработало. Сначала это казалось запутанным, но это сработало :) –

0

SytS имеет вопрос, когда какой-либо текст «добавляется», полосы прокрутки перемещается таким образом, что выбор идти в верхней части панели. Решение состоит в том, чтобы сохранить/восстановить позицию прокрутки с:

[System.Runtime.InteropServices.DllImport("User32.dll")] 
    extern static int GetScrollPos(IntPtr hWnd, int nBar); 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); 

This solution более полно для меня.

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