c# – Richtextbox将行号转换为滚动条位置

前端之家收集整理的这篇文章主要介绍了c# – Richtextbox将行号转换为滚动条位置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我现在可以使用这段代码同步我的两个RichTextBox
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 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,WM_VSCROLL,0);
    }
}

我可以在按键,向上和Vscroll事件时同步RichTextBox.
确实这不是我的目标,我想根据内容同步我的RichTextBoxes,
我需要的:

>获取当前行形式的非选定RichTextBox.
>使用另一个RichTextBox中的行号设置滚动条位置(不会丢失当前焦点的焦点).
>从滚动条位置获取行号.

注意:欢迎您询问是否需要更多详细信息.
提前致谢.

解决方法

据我所知,您需要根据行号同步2个RichTextBox上的滚动.如果我误解了它,请给我评论.

RichTextBox扩展:

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

用法

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

猜你在找的C#相关文章