2016-04-18 51 views
7

sono in grado ora di sincronizzare i miei due RichTextBox utilizzando questa pozione di codice:RichTextBox convertire un numero di riga per far scorrere barra di posizione

private const int SB_HORZ = 0x0; 
private const int SB_VERT = 0x1; 
private const int WM_HSCROLL = 0x114; 
private const int WM_VSCROLL = 0x115; 
private const int SB_THUMBPOSITION = 4; 
[DllImport("user32.dll", CharSet = CharSet.Auto)] 
private static extern int GetScrollPos(int hWnd, int nBar); 
[DllImport("user32.dll")] 
private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); 
[DllImport("user32.dll")] 
private static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam); 
internal int HScrollPos 
{ 
    private get { return GetScrollPos((int)this.Handle, SB_HORZ); } 
    set 
    { 
     SetScrollPos((IntPtr)this.Handle, SB_HORZ, value, true); 
     PostMessageA((IntPtr)this.Handle, WM_HSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); 
    } 
} 
internal int VScrollPos 
{ 
    get { return GetScrollPos((int)this.Handle, SB_VERT); } 
    set 
    { 
     SetScrollPos((IntPtr)this.Handle, SB_VERT, value, true); 
     PostMessageA((IntPtr)this.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); 
    } 
} 

posso sincronizzare il RichTextBoxes mentre premuto il tasto, e Vscroll evento. In effetti questo non è il mio obiettivo, voglio sincronizzare il RichTextBoxes basandosi sul contenuto, quello che mi serve:

  • ottenere la forma attuale linea non selezionata RichTextBox.
  • Impostare la posizione della barra di scorrimento utilizzando il numero di linea nell'altro RichTextBox (senza perdere lo stato attivo da quello corrente).
  • Ottieni il numero di riga dalla posizione della barra di scorrimento.

Nota: siete invitati a chiedere se avete bisogno di più dettagli.
Grazie in anticipo.

+0

Penso che questo esempio sarà utile per voi http://www.codeproject.com/Articles/12152/Numbering-lines- of-RichTextBox-in-NET – askeet

+0

Questa applicazione WinForm? – Ian

+0

sì, un modulo di Windows –

risposta

0

Da quello che ho capito, è necessario sincronizzare lo scorrimento su 2 RichTextBox in base al numero di riga. Lasciami un commento se ho frainteso.

RichTextBox esteso:

public class RichTextBoxEx : RichTextBox 
{ 
    // combination of multiple events that may cause focus(caret) to change 
    public event EventHandler FocusChanged; 

    public RichTextBoxEx() 
    { 
     this.KeyPress += (s, e) => RaiseFocusChanged(); 
     this.KeyDown += (s, e) => RaiseFocusChanged(); 
     this.KeyUp += (s, e) => RaiseFocusChanged(); 
     this.MouseClick += (s, e) => RaiseFocusChanged(); 
    } 

    private void RaiseFocusChanged() 
    { 
     var focusChanged = FocusChanged; 
     if (focusChanged != null) 
     { 
      focusChanged(this, null); 
     } 
    } 

    public int GetFirstSelectedLine() 
    { 
     var index = GetFirstCharIndexOfCurrentLine(); 
     return GetLineFromCharIndex(index); 
    } 
    public int GetFirstVisibleLine() 
    { 
     var index = GetCharIndexFromPosition(new Point(1, 1)); 
     return GetLineFromCharIndex(index); 
    } 

    public void ScrollToLine(int line) 
    { 
     if (line < 0) 
      throw new ArgumentOutOfRangeException("line cannot be less than 0"); 

     // save the current selection to be restored later 
     var selection = new { SelectionStart, SelectionLength }; 

     // select that line and scroll it to 
     Select(GetFirstCharIndexFromLine(line) + 1, 0); 
     ScrollToCaret(); 

     // restore selection 
     Select(selection.SelectionStart, selection.SelectionLength); 
    } 
} 

Usage:

void Main() 
{ 
    var mainScreenArea = Screen.PrimaryScreen.WorkingArea; 

    var rich1 = new RichTextBoxEx() { Width = mainScreenArea.Width/2 - 10, Dock = DockStyle.Left }; 
    var rich2 = new RichTextBoxEx() { Width = mainScreenArea.Width/2 - 10, Dock = DockStyle.Right }; 
    rich1.LoadFile(__RTF_FILE_0__); 
    rich2.LoadFile(__RTF_FILE_1__); 

    // pick one : 
    // synchronize by focus 
    rich1.FocusChanged += (s, e) => rich2.ScrollToLine(rich1.GetFirstSelectedLine()); 
    // synchronize by viewbox 
    // rich1.VScroll += (s, e) => rich2.ScrollToLine(rich1.GetFirstVisibleLine()); 

    var form = new Form(); 
    form.Controls.Add(rich1); 
    form.Controls.Add(rich2); 

    form.WindowState = FormWindowState.Maximized; 
    form.ShowDialog() 
}