winforms 具有行号的Windows窗体文本框?

r6l8ljro  于 2023-01-02  发布在  Windows
关注(0)|答案(6)|浏览(164)

我正在为我正在写的应用程序寻找一个免费的winforms组件。我基本上需要一个文本框,包含在侧栏的行号。能够在它的表格数据将是一个主要的优势了。
有人知道有什么预制部件可以做到这一点吗?

zf2sa74q

zf2sa74q1#

参考韦恩的帖子,下面是相关代码。它使用GDI在文本框旁边绘制行号。

Public Sub New()
    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call
    SetStyle(ControlStyles.UserPaint, True)
    SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    SetStyle(ControlStyles.DoubleBuffer, True)
    SetStyle(ControlStyles.ResizeRedraw, True)
End Sub

Private Sub RichTextBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.SelectionChanged
    FindLine()
    Invalidate()
End Sub

Private Sub FindLine()
    Dim intChar As Integer

    intChar = RichTextBox1.GetCharIndexFromPosition(New Point(0, 0))
    intLine = RichTextBox1.GetLineFromCharIndex(intChar)
End Sub

Private Sub DrawLines(ByVal g As Graphics, ByVal intLine As Integer)
    Dim intCounter As Integer, intY As Integer

    g.Clear(Color.Black)

    intCounter = intLine + 1
    intY = 2
    Do
        g.DrawString(intCounter.ToString(), Font, Brushes.White, 3, intY)
        intCounter += 1

        intY += Font.Height + 1
        If intY > ClientRectangle.Height - 15 Then Exit Do
    Loop
End Sub

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    DrawLines(e.Graphics, intLine)
End Sub

Private Sub RichTextBox1_VScroll(ByVal sender As Object, ByVal e As System.EventArgs) Handles RichTextBox1.VScroll
    FindLine()
    Invalidate()
End Sub

Private Sub RichTextBox1_UserScroll() Handles RichTextBox1.UserScroll
    FindLine()
    Invalidate()
End Sub

RichTextBox被如下重写:

Public Class UserControl1
Inherits System.Windows.Forms.RichTextBox

Public Event UserScroll()

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If m.Msg = &H115 Then
        RaiseEvent UserScroll()
    End If

    MyBase.WndProc(m)
End Sub
End Class

(Code由divil在xtremedotnettalk.com论坛上发布。)

yptwkmov

yptwkmov2#

看一下SharpDevelop C#编译器/IDE源代码。它们有一个复杂的文本框,上面有行号。您可以查看源代码,弄清楚它们在做什么,然后自己实现它。
下面是我所提到的一个例子:

(来源:sharpdevelop.net

huus2vyu

huus2vyu3#

http://www.xtremedotnettalk.com/showthread.php?s=&threadid=49661&highlight=RichTextBox上有一个项目,其代码可用。
您可以使用user/pass登录站点下载zip文件:布格梅诺特/布格梅诺特

u4dcyp6a

u4dcyp6a4#

CodePlex for .net中有一个源代码编辑组件http://www.codeplex.com/ScintillaNET

3phpmpom

3phpmpom5#

这里有一些C#代码可以做到这一点。它基于韦恩引用的www.example.com的代码xtremedotnettalk.com。我做了一些修改,使它实际上显示编辑器文本,而原始代码没有这样做。但是,公平地说,原始代码作者确实提到它需要改进。
下面是代码(编号文本框. cs)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace NumberedTextBoxLib {
  public partial class NumberedTextBox : UserControl {
    private int lineIndex = 0;

    new public String Text {
      get {
        return editBox.Text;
      }
      set {
        editBox.Text = value;
      }
    }

    public NumberedTextBox() {
      InitializeComponent();
      SetStyle(ControlStyles.UserPaint, true);
      SetStyle(ControlStyles.AllPaintingInWmPaint, true);
      SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
      SetStyle(ControlStyles.ResizeRedraw, true);
      editBox.SelectionChanged += new EventHandler(selectionChanged);
      editBox.VScroll += new EventHandler(OnVScroll);
    }

    private void selectionChanged(object sender, EventArgs args) {
      FindLine();
      Invalidate();
    }

    private void FindLine() {
      int charIndex = editBox.GetCharIndexFromPosition(new Point(0, 0));
      lineIndex = editBox.GetLineFromCharIndex(charIndex);
    }

    private void DrawLines(Graphics g) {
      int counter, y;
      g.Clear(BackColor);
      counter = lineIndex + 1;
      y = 2;
      int max = 0;
      while (y < ClientRectangle.Height - 15) {
        SizeF size = g.MeasureString(counter.ToString(), Font);
        g.DrawString(counter.ToString(), Font, new SolidBrush(ForeColor), new Point(3, y));
        counter++;
        y += (int)size.Height;
        if (max < size.Width) {
          max = (int) size.Width;
        }
      }
      max += 6;
      editBox.Location = new Point(max, 0);
      editBox.Size = new Size(ClientRectangle.Width - max, ClientRectangle.Height);
    }

    protected override void OnPaint(PaintEventArgs e) {
      DrawLines(e.Graphics);
      e.Graphics.TranslateTransform(50, 0);
      editBox.Invalidate();
      base.OnPaint(e);
    }

    ///Redraw the numbers when the editor is scrolled vertically
    private void OnVScroll(object sender, EventArgs e) {
      FindLine();
      Invalidate();
    }

  }
}

下面是Visual Studio设计器代码(NumberedTextBox.Designer.cs)

namespace NumberedTextBoxLib {
  partial class NumberedTextBox {
    /// Required designer variable.
    private System.ComponentModel.IContainer components = null;

    /// Clean up any resources being used.
    protected override void Dispose(bool disposing) {
      if (disposing && (components != null)) {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    private void InitializeComponent() {
      this.editBox = new System.Windows.Forms.RichTextBox();
      this.SuspendLayout();
      // 
      // editBox
      // 
      this.editBox.AcceptsTab = true;
      this.editBox.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                  | System.Windows.Forms.AnchorStyles.Left)
                  | System.Windows.Forms.AnchorStyles.Right)));
      this.editBox.Location = new System.Drawing.Point(27, 3);
      this.editBox.Name = "editBox";
      this.editBox.Size = new System.Drawing.Size(122, 117);
      this.editBox.TabIndex = 0;
      this.editBox.Text = "";
      this.editBox.WordWrap = false;
      // 
      // NumberedTextBox
      // 
      this.Controls.Add(this.editBox);
      this.Name = "NumberedTextBox";
      this.Size = new System.Drawing.Size(152, 123);
      this.ResumeLayout(false);

    }

    private System.Windows.Forms.RichTextBox editBox;
  }
}
ckx4rj1h

ckx4rj1h6#

我猜这取决于字体大小,我使用了“Courier New,9pt,style=bold”

  • 添加了平滑滚动的修复(不是逐行)
  • 增加了大文件的修复,当滚动值超过16位。
    编号文本框.cs
public partial class NumberedTextBox : UserControl
{
    private int _lines = 0;

    [Browsable(true), 
        EditorAttribute("System.ComponentModel.Design.MultilineStringEditor, System.Design","System.Drawing.Design.UITypeEditor")]
    new public String Text
    {
        get
        {
            return editBox.Text;
        }
        set
        {
            editBox.Text = value;
            Invalidate();
        }
    }

    private Color _lineNumberColor = Color.LightSeaGreen;

    [Browsable(true), DefaultValue(typeof(Color), "LightSeaGreen")]
    public Color LineNumberColor {
        get{
            return _lineNumberColor;
        }
        set
        {
            _lineNumberColor = value;
            Invalidate();
        }
    }

    public NumberedTextBox()
    {
        InitializeComponent();

        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        editBox.SelectionChanged += new EventHandler(selectionChanged);
        editBox.VScroll += new EventHandler(OnVScroll);
    }

    private void selectionChanged(object sender, EventArgs args)
    {
        Invalidate();
    }

    private void DrawLines(Graphics g)
    {
        g.Clear(BackColor);
        int y = - editBox.ScrollPos.Y;
        for (var i = 1; i < _lines + 1; i++)
        {
            var size = g.MeasureString(i.ToString(), Font);
            g.DrawString(i.ToString(), Font, new SolidBrush(LineNumberColor), new Point(3, y));
            y += Font.Height + 2;
        }
        var max = (int)g.MeasureString((_lines + 1).ToString(), Font).Width + 6;
        editBox.Location = new Point(max, 0);
        editBox.Size = new Size(ClientRectangle.Width - max, ClientRectangle.Height);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        _lines = editBox.Lines.Count();
        DrawLines(e.Graphics);
        e.Graphics.TranslateTransform(50, 0);
        editBox.Invalidate();
        base.OnPaint(e);
    }

    private void OnVScroll(object sender, EventArgs e)
    {
        Invalidate();
    }

    public void Select(int start, int length)
    {
        editBox.Select(start, length);
    }

    public void ScrollToCaret()
    {
        editBox.ScrollToCaret();
    }

    private void editBox_TextChanged(object sender, EventArgs e)
    {
        Invalidate();
    }
}

public class RichTextBoxEx : System.Windows.Forms.RichTextBox
{
    private double _Yfactor = 1.0d;

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, Int32 wMsg, Int32 wParam, ref Point lParam);

    private enum WindowsMessages
    {
        WM_USER = 0x400,
        EM_GETSCROLLPOS = WM_USER + 221,
        EM_SETSCROLLPOS = WM_USER + 222
    }

    public Point ScrollPos
    {
        get
        {
            var scrollPoint = new Point();
            SendMessage(this.Handle, (int)WindowsMessages.EM_GETSCROLLPOS, 0, ref scrollPoint);
            return scrollPoint;
        }
        set
        {
            var original = value;
            if (original.Y < 0)
                original.Y = 0;
            if (original.X < 0)
                original.X = 0;

            var factored = value;
            factored.Y = (int)((double)original.Y * _Yfactor);

            var result = value;

            SendMessage(this.Handle, (int)WindowsMessages.EM_SETSCROLLPOS, 0, ref factored);
            SendMessage(this.Handle, (int)WindowsMessages.EM_GETSCROLLPOS, 0, ref result);

            var loopcount = 0;
            var maxloop = 100;
            while (result.Y != original.Y)
            {
                // Adjust the input.
                if (result.Y > original.Y)
                    factored.Y -= (result.Y - original.Y) / 2 - 1;
                else if (result.Y < original.Y)
                    factored.Y += (original.Y - result.Y) / 2 + 1;

                // test the new input.
                SendMessage(this.Handle, (int)WindowsMessages.EM_SETSCROLLPOS, 0, ref factored);
                SendMessage(this.Handle, (int)WindowsMessages.EM_GETSCROLLPOS, 0, ref result);

                // save new factor, test for exit.
                loopcount++;
                if (loopcount >= maxloop || result.Y == original.Y)
                {
                    _Yfactor = (double)factored.Y / (double)original.Y;
                    break;
                }
            }
        }
    }
}

编号文本框.设计器.cs

partial class NumberedTextBox
{
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.editBox = new WebTools.Controls.RichTextBoxEx();
        this.SuspendLayout();
        // 
        // editBox
        // 
        this.editBox.AcceptsTab = true;
        this.editBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
        | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));
        this.editBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
        this.editBox.Location = new System.Drawing.Point(27, 3);
        this.editBox.Name = "editBox";
        this.editBox.ScrollPos = new System.Drawing.Point(0, 0);
        this.editBox.Size = new System.Drawing.Size(120, 115);
        this.editBox.TabIndex = 0;
        this.editBox.Text = "";
        this.editBox.WordWrap = false;
        this.editBox.TextChanged += new System.EventHandler(this.editBox_TextChanged);
        // 
        // NumberedTextBox
        // 
        this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        this.Controls.Add(this.editBox);
        this.Name = "NumberedTextBox";
        this.Size = new System.Drawing.Size(150, 121);
        this.ResumeLayout(false);

    }

    private RichTextBoxEx editBox;

    #endregion
}

相关问题