Nel modulo della mia domanda, ho due oggetti RichTextBox
. Entrambi avranno sempre lo stesso numero di righe di testo. Mi piacerebbe "sincronizzare" lo scorrimento verticale tra questi due, in modo che quando l'utente cambia la posizione di scorrimento verticale su uno, l'altro scorre lo stesso importo. Come potrei andare a fare questo?C#: sincronizza la posizione di scorrimento di due RichTextBox?
risposta
Ho fatto questo per un piccolo progetto qualche tempo fa, ed ecco la soluzione semplicistica che ho trovato.
Creare un nuovo controllo per subclassing RichTextBox:
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);
}
}
Aggiungere il nuovo controllo al form e per ogni controllo di avvisare esplicitamente le altre istanze del controllo che la sua posizione VScroll è cambiata. Somthing come questo:
private void scrollSyncTxtBox1_vScroll(Message msg) {
msg.HWnd = scrollSyncTxtBox2.Handle;
scrollSyncTxtBox2.PubWndProc(ref msg);
}
penso che questo codice ha problemi se tutti i controlli 'collegate' non hanno lo stesso numero di righe visualizzabili.
Grazie Jay per la risposta; dopo un po 'di ricerche ho trovato anche il metodo descritto here. Lo traccerò qui sotto per chiunque sia interessato.
In primo luogo, dichiarare le seguenti enumerazioni:
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
}
Quindi, aggiungere i riferimenti esterni per GetScrollPos
e 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);
Infine, aggiungere un gestore eventi per l'evento VScroll
della appropriata 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));
}
In questo caso, la posizione di scorrimento verticale richTextBox2
s' sarà sincronizzato con richTextBox1
.
Sommario grande . Ho risparmiato molto tempo. Grazie! –
quale sarebbe il codice esadecimale per WM_HSCROLL? – Logerfo
Una variante dell'approccio di sottoclasse di Jay può essere trovato nel post di Joseph Kingry qui: Synchronizing Multiline Textbox Positions in C#. L'approccio di Joseph include anche sottoclassi, ma non richiede un gestore di eventi _VScroll. Ho usato questo approccio per creare un legame a 3 vie tra 3 caselle e aggiunto WM_HSCROLL.
[Visual Studio C# 2010 Express, v10.0.30319 in un'installazione 7 a 64 bit di Windows]
ho usato la soluzione di Donut postato sopra, ma ha trovato un problema quando si scorre fino alla fine della RichTextBoxes che contengono molte linee.
Se il risultato di GetScrollPos()
è >0x7FFF
allora quando nPos
viene spostato, viene impostato il bit superiore. La creazione di IntPtr
con la variabile wParam
risultante avrà quindi esito negativo con un OverflowException
. Si può facilmente verificare con il seguente (la seconda linea non riuscirà):
IntPtr ip = new IntPtr(0x7FFF0000);
IntPtr ip2 = new IntPtr(0x80000000);
Una versione di SendMessage()
che utilizza UIntPtr
sembrerebbe essere una soluzione, ma non ho potuto ottenere quello per funzionare.Così, ho utilizzare il seguente:
[DllImport("User32.dll")]
public extern static int SendMessage(IntPtr hWnd, uint msg, UInt32 wParam, UInt32 lParam);
Questo dovrebbe essere buono fino a 0xffff
, ma vorrei riuscire dopo. Non ho ancora riscontrato un risultato >0xffff
da GetScrollPos()
e si presume che User32.dll sia improbabile che disponga di una versione a 64 bit di SendCommand()
, ma qualsiasi soluzione a tale problema sarebbe molto apprezzata.
- 1. Come si sincronizza la posizione di scorrimento di due div?
- 2. sincronizza lo scorrimento di due div
- 3. Scorrimento automatico in RichTextBox C# WinForms
- 4. Scorrimento orizzontale RichTextBox non funzionante
- 5. Imposta posizione di scorrimento
- 6. C# RichTextBox problema di selezione
- 7. CListCtrl: come mantenere la posizione di scorrimento?
- 8. Chrome ricorda la posizione di scorrimento
- 9. ListView ottiene la posizione di scorrimento?
- 10. Windows Form RichTextBox posizione del cursore
- 11. Come salvare la posizione di scorrimento di ListView
- 12. Modifica posizione barra di scorrimento
- 13. Impedire lo scorrimento automatico in RichTextBox
- 14. trovare la posizione di scorrimento massima di una pagina
- 15. JavaScript sincronizza due array (di oggetti)/trova delta
- 16. C# Printing (RichTextBox)
- 17. Come mantenere la posizione di scorrimento usando la Pagina Master?
- 18. Aggiorna la posizione di scorrimento di UITextView su iPhone
- 19. Come posso impostare la posizione di scorrimento di un UIScrollView?
- 20. Come posso controllare la velocità di scorrimento di recyclerView.smoothScrollToPosition (posizione)
- 21. C#/WPF: Disabilita Text-Wrap di RichTextBox
- 22. RichTextBox convertire un numero di riga per far scorrere barra di posizione
- 23. Impostazione di una posizione barra di scorrimento
- 24. Come "ricordare" la posizione di scorrimento in angularJS w/Ui.ROUTER
- 25. recyclerview vista interna scorrimento influisce posizione di scorrimento
- 26. Scorrimento di due UITableViews insieme
- 27. Posizione fissa - Scorrimento orizzontale
- 28. come ricordare la posizione di scorrimento della pagina
- 29. Trova la posizione verticale della barra di scorrimento senza jQuery
- 30. Come ottenere la posizione della barra di scorrimento con Javascript?
Questo metodo funziona correttamente per lo scorrimento spostando la barra di scorrimento. Ma le barre di scorrimento non sono sincronizzate quando (1) scorre con la rotellina del mouse (2) scorrendo con i tasti 'pagina giù' o' pagina su' - scorrendo premendo i tasti freccia – twnaing
@Jay riggs 'System.Windows.Forms.RichTextBox' non contiene una definizione per "PubWndProc" e nessun metodo di estensione "PubWndProc" che accetta un primo argomento di tipo "System.Windows.Forms.RichTextBox" potrebbe essere trovato (ti manca una direttiva using o un riferimento di assembly?) – Pomster