En el formulario de mi solicitud, tengo dos objetos RichTextBox
. Ambos siempre tendrán la misma cantidad de líneas de texto. Me gustaría "sincronizar" el desplazamiento vertical entre estos dos, de modo que cuando el usuario cambie la posición de desplazamiento vertical en uno, el otro recorra la misma cantidad. ¿Cómo puedo hacer esto?C#: ¿sincroniza la posición de desplazamiento de dos RichTextBoxes?
Respuesta
Hace un tiempo hice esto para un proyecto pequeño, y aquí está la solución simplista que encontré.
Crear un nuevo control RichTextBox por subclases:
public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTextBox
{
public event vScrollEventHandler vScroll;
public delegate void vScrollEventHandler(System.Windows.Forms.Message message);
public const int WM_VSCROLL = 0x115;
protected override void WndProc(ref System.Windows.Forms.Message msg) {
if (msg.Msg == WM_VSCROLL) {
if (vScroll != null) {
vScroll(msg);
}
}
base.WndProc(ref msg);
}
public void PubWndProc(ref System.Windows.Forms.Message msg) {
base.WndProc(ref msg);
}
}
Añadir el nuevo control a su forma y para cada control notificar de forma explícita las otras instancias del control que su posición VScroll ha cambiado. Algo como esto:
private void scrollSyncTxtBox1_vScroll(Message msg) {
msg.HWnd = scrollSyncTxtBox2.Handle;
scrollSyncTxtBox2.PubWndProc(ref msg);
}
creo que este código tiene problemas si todos los controles vinculados '' no tienen el mismo número de líneas que se pueden visualizar.
Gracias Jay por su respuesta; después de buscar un poco más, también encontré el método descrito here. Lo resumiré a continuación para cualquier otra persona interesada.
En primer lugar, declarar las siguientes enumeraciones:
public enum ScrollBarType : uint {
SbHorz = 0,
SbVert = 1,
SbCtl = 2,
SbBoth = 3
}
public enum Message : uint {
WM_VSCROLL = 0x0115
}
public enum ScrollBarCommands : uint {
SB_THUMBPOSITION = 4
}
A continuación, añadir referencias externas a GetScrollPos
y SendMessage
.
[DllImport("User32.dll")]
public extern static int GetScrollPos(IntPtr hWnd, int nBar);
[DllImport("User32.dll")]
public extern static int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
Por último, añadir un controlador de eventos para el VScroll
caso de la apropiada RichTextBox
:
private void myRichTextBox1_VScroll(object sender, EventArgs e)
{
int nPos = GetScrollPos(richTextBox1.Handle, (int)ScrollBarType.SbVert);
nPos <<= 16;
uint wParam = (uint)ScrollBarCommands.SB_THUMBPOSITION | (uint)nPos;
SendMessage(richTextBox2.Handle, (int)Message.WM_VSCROLL, new IntPtr(wParam), new IntPtr(0));
}
En este caso, la posición de desplazamiento vertical richTextBox2
's se sincronizará con richTextBox1
.
Gran resumen . Ahorré mi montón de tiempo. ¡Gracias! –
¿cuál sería el código hexadecimal para WM_HSCROLL? – Logerfo
Una variación del enfoque de la subclase de Jay se puede encontrar en la publicación de Joseph Kingry aquí: Synchronizing Multiline Textbox Positions in C#. El enfoque de Joseph también tiene subclases, pero no requiere un manejador de eventos _VScroll. Usé ese enfoque para hacer un enlace de 3 vías entre 3 cuadros y agregué WM_HSCROLL.
[Visual Studio C# 2010 Express, v10.0.30319 en una instalación de Windows 7 64 bits]
He usado la solución de Donut publicado anteriormente, pero se encontró con un problema cuando se desplaza hasta el final de RichTextBoxes que contienen muchas líneas.
Si el resultado de GetScrollPos()
es >0x7FFF
entonces cuando se cambia nPos
, se establece el bit superior. La creación del IntPtr
con la variable wParam
resultante fallará con un OverflowException
. Se puede probar fácilmente esto con la siguiente (la segunda línea fallará):
IntPtr ip = new IntPtr(0x7FFF0000);
IntPtr ip2 = new IntPtr(0x80000000);
Una versión de SendMessage()
que utiliza UIntPtr
parecería ser una solución, pero no pude conseguir que funcione.Por lo tanto, no tengo utilice la siguiente:
[DllImport("User32.dll")]
public extern static int SendMessage(IntPtr hWnd, uint msg, UInt32 wParam, UInt32 lParam);
Esto debe ser bueno hasta 0xffff
, pero fallaría después de eso. Todavía no he experimentado un resultado >0xffff
de GetScrollPos()
, y supongo que es poco probable que User32.dll tenga una versión de 64 bits de SendCommand()
, pero cualquier solución a ese problema sería muy apreciada.
- 1. ¿Cómo sincronizo la posición de desplazamiento de dos divisiones?
- 2. Establecer la posición de desplazamiento
- 3. CSS establecer la posición de desplazamiento predeterminada
- 4. Mostrar div cuando la posición de desplazamiento
- 5. CListCtrl: ¿Cómo mantener la posición de desplazamiento?
- 6. posición de desplazamiento con jQuery
- 7. Sincronizar la posición de dos vistas ScrollView
- 8. Posición fija - Desplazamiento horizontal
- 9. C#: Cómo cambiar la posición de dos controles winform
- 10. Obtener desplazamiento Posición Porcentaje
- 11. posición extraña de la barra de desplazamiento de iScroll
- 12. Cambio de la posición de la barra de desplazamiento
- 13. cómo recordar la posición de desplazamiento de la página
- 14. ¿Cambiar la posición de la barra de desplazamiento en TextBox?
- 15. Obtener la posición del ratón en desplazamiento
- 16. Jquery soluciona la posición div cuando div alcanza la posición de pantalla, no la posición de desplazamiento
- 17. js/css: desactivar la barra de desplazamiento, pero mantener la posición de desplazamiento
- 18. Posición de desplazamiento perdida al ocultar div
- 19. ¿Cómo obtengo la posición de desplazamiento de un documento?
- 20. PrimeFaces barra de desplazamiento de datos en la posición deseada
- 21. Cómo obtener la última posición de vista de desplazamiento, scrollview
- 22. Actualice la posición de desplazamiento de UITextView en el iPhone
- 23. WPF zoom de lienzo y mantener la posición de desplazamiento
- 24. ¿Cómo puedo establecer la posición de desplazamiento de un UIScrollView?
- 25. Configurar una posición de la barra de desplazamiento
- 26. MousePressEvent, desplazamiento de posición en QGraphicsView
- 27. Desplazamiento simultáneo de dos UITableViews
- 28. C# Panel con desplazamiento automático - Restablecimiento de la posición de Srollbar en un foco de control
- 29. Recordar la posición de desplazamiento en el elemento QML
- 30. cómo establecer la posición de desplazamiento en uiwebview
Este método funciona bien para desplazarse moviendo la barra de desplazamiento. Pero las barras de desplazamiento no están sincronizadas cuando (1) se desplaza con la rueda del mouse (2) desplazándose por las teclas 'page down' o' page up' - se desplaza presionando las teclas de flecha – twnaing
@Jay riggs 'System.Windows.Forms.RichTextBox' no contiene una definición para 'PubWndProc' y no se puede encontrar ningún método de extensión 'PubWndProc' que acepte un primer argumento de tipo 'System.Windows.Forms.RichTextBox' (¿falta una directiva using o una referencia de ensamblado?) – Pomster