带有用于输入的虚线的文本框 [英] TextBox with dotted lines for typing
问题描述
我想创建一个虚线,用作在其上输入文本而不是使用文本框的输入.
例如:
而不是文本框:
我想做这样的事情:
并且能够在上面打字.
您可以尝试使用从 TextBox 派生的自定义控件.
覆盖其 WndProc 并处理
如果您不知道如何使用此代码:
- 向您的项目添加一个新类并将其命名为
TextBoxBaseline
. - 复制您在此处找到的
using
指令并将它们粘贴到类的顶部. - 复制其余代码并替换类文件中的默认类定义,而不删除命名空间.
- 构建项目.
- 您将在工具箱中找到
TextBoxBaseline
控件.像往常一样打开一个表单并将其放在上面.
I want to create a dotted lines that is used as input for typing text on it instead using a text box.
For example:
Instead of text box:
I want make something like this:
and to be able to type on it.
You can try with a Custom Control derived from TextBox.
Overriding its WndProc and handling WM_PAINT
, you can draw a dotted/dashed line (or anything else) inside the edit control's ClientArea. Then refresh the line drawing when keys are pressed, so the line is not erased.
WM_KEYDOWN
, WM_LBUTTONDOWN
and WM_CAPTURECHANGED
are also handled, since these can (will) cause the painting of the background.
The position of the base line is calculated using the FontFamily's GetLineSpacing() and GetCellAscent() methods, then moved down the size of the Pen used to draw the line.
OnFontChanged() is overridden to get a notification when the Font changes.
Some more info here: Properly draw text using Graphics Path
It's a little raw, but see how it goes :)
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
[ToolboxItem(true)]
[DesignerCategory("Code")]
public class TextBoxBaseline : TextBox
{
private const int WM_PAINT = 0x000F;
private const int WM_KEYDOWN = 0x0100;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_CAPTURECHANGED = 0x0215;
private float m_lnSpacing = 0.0f;
private float m_cellAscent = 0.0f;
public TextBoxBaseline() {
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.BorderStyle = BorderStyle.None;
}
protected override void OnFontChanged(EventArgs e) {
base.OnFontChanged(e);
m_lnSpacing = Font.FontFamily.GetLineSpacing(Font.Style);
m_cellAscent = Font.FontFamily.GetCellAscent(Font.Style);
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
switch (m.Msg) {
case WM_PAINT:
using (var g = Graphics.FromHwnd(this.Handle))
using (Pen pen = new Pen(Color.DimGray, 1)) {
pen.DashStyle = DashStyle.Dash;
int baseLine = (int)(Font.GetHeight(g) * m_cellAscent / m_lnSpacing + pen.Width);
g.DrawLine(pen, 1, baseLine, ClientSize.Width - 1, baseLine);
m.Result = IntPtr.Zero;
}
break;
case WM_KEYDOWN:
case WM_LBUTTONDOWN:
case WM_CAPTURECHANGED:
this.Invalidate();
break;
}
}
}
It looks like this:
If you don't know how to used this code:
- Add a new class to your Project and name it
TextBoxBaseline
. - Copy the
using
directives you find here and paste them on top of the class. - Copy the rest of the code and replace the default class definition in your class file, without removing the namespace.
- Build the Project.
- You'll find the
TextBoxBaseline
Control in the ToolBox. Open up a Form and drop it on it as usual.
这篇关于带有用于输入的虚线的文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!