将指南添加到 TextBox/RichTextBox
Adding guidelines to a TextBox/RichTextBox
有没有办法在多行文本框或富文本框上显示网格线?
也许通过覆盖 OnPaint 事件?
我正在使用文本框插入地址信息,对于每一行它会是这样的:
Street
City
Country
etc.
我在 C# 中使用 WinForms。
从这段代码开始:
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
您可以使用以下方法之一进行操作:
- 自定义 TextBox 的画图
- 使用 RTF 技巧
这是这两种方式的屏幕截图:
如果您确实需要此功能,我建议使用第一种方法。
1-自定义TextBox的Paint
自定义文本框绘制并不简单。您可以通过不同方式自定义 TextBox 的绘制。这里有两种自定义TextBox绘画的方法。
1-1 使用 NativeWindow 自定义 TextBox 的 Paint
以这种方式应该使用 NativeWindow 对 TextBox 进行子类化,并在 window 过程中处理 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- 创建透明文本框
这样你应该先制作一个透明的文本框,然后将它的背景设置为你想要的网格线。由于这种方式也是创建自定义绘画文本框的一种方式,您也可以自定义该文本框的绘画并根据您的意愿进行调整。
这是 link 2 篇涵盖透明文本框和透明 RichTextBox 的精彩文章:
- Alpha Blended (Transparent Capable) TextBox and RichTextBox
- AlphaBlendTextBox - A transparent/translucent textbox for .NET
2- 使用 RTF 技巧
有一些 rtf 技巧可以用来在 RichTextBox 中显示网格线。最好的技巧之一是使用 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}
}";
重要提示:在代码编辑器中粘贴以上代码时,注意不要在富文本字符前放置缩进。如果 Visual studio 在它们之前插入缩进,则删除所有缩进。
有没有办法在多行文本框或富文本框上显示网格线? 也许通过覆盖 OnPaint 事件?
我正在使用文本框插入地址信息,对于每一行它会是这样的:
Street
City
Country
etc.
我在 C# 中使用 WinForms。
从这段代码开始:
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
您可以使用以下方法之一进行操作:
- 自定义 TextBox 的画图
- 使用 RTF 技巧
这是这两种方式的屏幕截图:
如果您确实需要此功能,我建议使用第一种方法。
1-自定义TextBox的Paint
自定义文本框绘制并不简单。您可以通过不同方式自定义 TextBox 的绘制。这里有两种自定义TextBox绘画的方法。
1-1 使用 NativeWindow 自定义 TextBox 的 Paint
以这种方式应该使用 NativeWindow 对 TextBox 进行子类化,并在 window 过程中处理 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- 创建透明文本框
这样你应该先制作一个透明的文本框,然后将它的背景设置为你想要的网格线。由于这种方式也是创建自定义绘画文本框的一种方式,您也可以自定义该文本框的绘画并根据您的意愿进行调整。
这是 link 2 篇涵盖透明文本框和透明 RichTextBox 的精彩文章:
- Alpha Blended (Transparent Capable) TextBox and RichTextBox
- AlphaBlendTextBox - A transparent/translucent textbox for .NET
2- 使用 RTF 技巧
有一些 rtf 技巧可以用来在 RichTextBox 中显示网格线。最好的技巧之一是使用 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}
}";
重要提示:在代码编辑器中粘贴以上代码时,注意不要在富文本字符前放置缩进。如果 Visual studio 在它们之前插入缩进,则删除所有缩进。