2016-04-18 5 views
7

Ich bin in der Lage zu blättern meine beiden RichTextBox mit diesem Trank von Code zu synchronisieren:RichTextBox eine Zeilennummer konvertieren bar Position jetzt

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); 
    } 
} 

ich die RichTextBoxes während Taste gedrückt synchronisieren können, und Vscroll Ereignis. der Tat ist dies nicht mein Ziel, ich will meine RichTextBoxes Stationierung auf den Inhalt synchronisieren, Was ich brauche:

  • Erhalten Sie die aktuelle Zeile Form RichTextBox nicht ausgewählt.
  • Stellen Sie die Scroll-Balkenposition mit der Zeilennummer in der anderen RichTextBox ein (ohne den Fokus vom aktuellen zu verlieren).
  • Die Zeilennummer von der Bildlaufleistenposition abrufen.

Hinweis: Sie willkommen sind, zu fragen, ob Sie mehr Informationen benötigen.
Vielen Dank im Voraus.

+0

Ich denke, das Beispiel für Sie nützlich sein wird http://www.codeproject.com/Articles/12152/Numbering-lines- von-RichTextBox-in-NET – askeet

+0

Ist diese WinForm-Anwendung? – Ian

+0

ja, ein Windows-Formular –

Antwort

0

Von was ich verstehe, müssen Sie Scrollen auf 2 RichTextBox es basierend auf der Zeilennummer synchronisieren. Hinterlasse mir einen Kommentar, wenn ich es falsch verstanden habe.

RichTextBox erweitert:

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); 
    } 
} 

Verbrauch:

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() 
}