2009-03-09 22 views
9

Tengo una ventana de registro de datos de solo lectura que implementé usando el control RichTextBox. Me gustaría poder deshabilitar el desplazamiento automático que ocurre cuando el usuario hace clic en el control para que el usuario pueda seleccionar un registro específico para operaciones de copiar/pegar o lo que sea. Sin embargo, tan pronto como el usuario hace clic en RichTextBox, se desplaza automáticamente hacia abajo, lo que dificulta esta tarea.Prevenir Autoscroll en RichTextBox

¿Alguien sabe una manera de anular este comportamiento?

Gracias!

Respuesta

6

que te pueden echar un vistazo a hacer algo como esto:

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

entonces en su método que añade datos de registro (Estoy haciendo algunas suposiciones aquí) que podría hacer algo como esto:

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

Hice una pequeña aplicación de prueba con un temporizador que hizo el apéndice en el richtextbox y lo detuvo de desplazarse para que pudiera hacer la selección de texto. Tiene algunos problemas de posición y no es perfecto, pero tal vez lo ayudará a avanzar hacia una solución propia.

¡Todo lo mejor!

11

El control RichTextBox se desplaza automáticamente a la selección actual, si la selección no está oculta. RichTextBox.AppendText(), además de agregar texto, también modifica la selección actual y, por lo tanto, desencadena indirectamente el comportamiento de "autoscroll". Tenga en cuenta que si RichTextBox.HideSelection se establece en verdadero, la selección se ocultará cuando el control no esté enfocado; esto explica el comportamiento que describió, donde el desplazamiento automático ocurre solo cuando el usuario hace clic en el control. (Dando así el foco) Para evitar esto, es necesario hacer lo siguiente al anexar texto:

  1. copia de seguridad de la selección inicial
  2. unfocus el control
  3. Ocultar selección (a través de un mensaje de Windows)
  4. AppendText
  5. Restaurar la selección inicial selección
  6. Unhide
  7. Refocus el control

Es posible que también desee comprobar si la selección ya está al final del texto, y permitir el comportamiento de desplazamiento automático, si es así, esto esencialmente emula el comportamiento de la ventana de resultados de Visual Studio. Por ejemplo: solución

[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

¡Su solución funciona como un encanto! Probé muchos otros enfoques para evitar que mi RichTextBox se desplazara después de realizar cambios de formato, y este fue el único que funcionó. Parecía intrincado al principio, pero funcionó :) –

0

de SytS tiene un problema, cuando un texto se "añade", la barra de desplazamiento se mueve de tal manera que la selección vaya a la parte superior del panel. Una solución es salvar/restaurar la posición de desplazamiento con:

[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 es más completa para mí.