在其上键入文本的虚线-C#

问题描述

我想创建一条虚线,用作在其上键入文本的输入,而不是使用文本框。 例如: 代替文本框: Text Box

我想做这样的事情:

Dotted lines

并能够在其上输入。

解决方法

在承载无边界TextBox控件的面板的Paint事件中,您可以像这样绘制它:

private void Panel1_Paint(object sender,PaintEventArgs e) {
  using (Pen p = new Pen(Color.Black)) {
    p.DashStyle = DashStyle.Dash;
    e.Graphics.DrawLine(p,new Point(textBox1.Left,textBox1.Bottom + 2),new Point(textBox1.Right,textBox1.Bottom + 2));
  }
}

最终看起来像这样:

enter image description here

,

您可以尝试使用从TextBox派生的自定义控件。
覆盖其WndProc并处理WM_PAINT,您可以在编辑控件的ClientArea内部绘制虚线(或其他虚线)。然后在按下键时刷新线条图,这样线条就不会被擦除。

WM_KEYDOWNWM_LBUTTONDOWNWM_CAPTURECHANGED也被处理,因为它们可以(将)导致背景的绘制。

使用FontFamilyGetLineSpacing()GetCellAscent()方法计算基线的位置,然后向下移动用于划清界线。
字体更改时,OnFontChanged()被覆盖以获取通知。

此处有更多信息:Properly draw text using Graphics Path

有点原始,但是看看进展如何:)

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

它看起来像这样:

TextBox Baseline TextBox Baseline dark TextBox Baseline light


如果您不知道如何使用此代码:

  • 在您的项目中添加一个新类,并将其命名为TextBoxBaseline
  • 复制您在此处找到的using指令,并将其粘贴到类的顶部。
  • 复制其余代码并替换类文件中的默认类定义,而不删除名称空间。
  • 构建项目。
  • 您将在工具箱中找到TextBoxBaseline控件。像往常一样打开一个窗体并将其放在上面。