繁体   English   中英

将准则添加到TextBox / RichTextBox

[英]Adding guidelines to a TextBox/RichTextBox

有什么方法可以在多行文本框或RichTextBox上显示网格线? 也许是通过覆盖OnPaint事件?

我正在使用文本框插入地址信息,对于每一行,它类似于:



国家
等等

我在C#中使用WinForms。

您可以使用以下方法之一进行操作:

  • 自定义TextBox的绘制
  • 使用RTF技巧

这是这两种方式的屏幕截图:

在此处输入图片说明

如果您确实需要此功能,建议使用第一种方法。

1-自定义TextBox的绘制


自定义文本框绘制并不简单。 您可以用不同的方式自定义TextBox的绘制。 这是自定义TextBox绘画的2种方法。

1-1使用NativeWindow自定义TextBox的绘制


这样,应该使用NativeWindow子类化TextBox并在窗口过程中处理WM_PAINT。 这是实现您所需内容的完整代码清单。

要使用代码,只需将您的文本框传递到CustomPaintTextBox的实例即可:

var t = new CustomControls.CustomPaintTextBox(this.textBox1);

这是CustomPaintTextBox的代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace CustomControls
{
    public class CustomPaintTextBox : NativeWindow
    {
        private TextBox parentTextBox;
        private const int WM_PAINT = 15;
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_PAINT: 
                    // invalidate textbox to make it refresh
                    parentTextBox.Invalidate();
                    // call default paint
                    base.WndProc(ref m);
                    // draw custom paint
                    this.CustomPaint();
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
        public CustomPaintTextBox(TextBox textBox)
        {
            this.parentTextBox = textBox;
            textBox.TextChanged += textBox_TextChanged;
            // subscribe for messages
            this.AssignHandle(textBox.Handle);
        }
        void textBox_TextChanged(object sender, EventArgs e)
        {
            CustomPaint();
        }
        private void CustomPaint()
        {
            var g= this.parentTextBox.CreateGraphics();
            float y = 0;
            var lineHeight = g.MeasureString("X", this.parentTextBox.Font).Height;
            while (y < this.parentTextBox.Height)
            {
                y += lineHeight;
                g.DrawLine(Pens.Red, 0f, y, (float)this.parentTextBox.Width, y);
            }
        }
    }
}

该解决方案的好处在于它非常简单,并且不需要新的继承文本框。

1-2-创建透明文本框


这样,您应该首先制作一个透明的文本框,然后将其背景设置为所需的网格线。 由于这种方法也是创建自定义绘画文本框的一种方法,因此您也可以自定义该文本框的绘画并将其弯曲。

这是2条涵盖透明文本框和透明RichTextBox的重要文章的链接:

2-使用RTF技巧


除了在RichTextBox中显示网格线外,还有一些rtf技巧。 最好的技巧之一是在RTF中使用表格。 在下面的代码中,我们使用了3行,其中包含一个宽度为2000缇的单元格:

this.richTextBox1.SelectAll();
this.richTextBox1.SelectedRtf =
@"{\rtf1\ansi\deff0
{\trowd
\cellx2000
\intbl Street\cell
\row}
{\trowd
\cellx2000
\intbl City\cell
\row}
{\trowd
\cellx2000
\intbl Country\cell
\row}
}";

重要说明:在代码编辑器中粘贴以上代码时,请注意不要在RTF字符前插入缩进。 如果Visual Studio在它们之前插入了缩进,则将删除所有缩进。

从以下代码开始:

class GridLineTextBox : TextBox
{
    public GridLineTextBox()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var y = 0f;
        var lineHeight = e.Graphics.MeasureString("W", Font).Height;
        while (y < e.ClipRectangle.Height)
        {
            y += lineHeight;
            e.Graphics.DrawLine(System.Drawing.Pens.Aqua, new PointF(0, y), new PointF(e.ClipRectangle.Width, y));
        }
    }
}

也许是RTF模板文件:

{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\trowd \trgaph180
\cellx3440\pard\intbl [0]\cell
\row
\trowd \trgaph180
\cellx3440\pard\intbl [1]\cell
\row
\trowd \trgaph180
\cellx3440\pard\intbl [2]\cell
\row
\para}

Dim fileContents As String
fileContents = My.Computer.FileSystem.ReadAllText("C:\temp\template.rtf")
Dim sRTF As String = fileContents.Replace("[0]", "line 1").Replace("[1]", "line 2").Replace("[2]", "line 3")
RichTextBox1.Rtf = sRTF

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM