【问题标题】:TextBox with dotted lines for typing [closed]带有用于输入的虚线的文本框 [关闭]
【发布时间】:2020-11-03 23:35:34
【问题描述】:

我想创建一个虚线,用作在其上输入文本而不是使用文本框的输入。
例如:
而不是文本框:

我想做这样的事情:

并且能够在上面打字。

【问题讨论】:

  • 那些虚线在文本框内吗?就像如果您按“A”,它会替换其中一个破折号?还是破折号像下划线?
  • 我不想要文本框的边框,我想要像下划线一样的虚线并且能够在上面输入
  • 在面板(或用户控件)内放置一个无边框文本框,并在该面板(或用户控件)的绘制事件中绘制虚线。
  • @LabinotAziri 你做过任何研究吗?有很多关于如何使用控件的绘制事件的资源

标签: c# winforms graphics textbox windows-forms-designer


【解决方案1】:

在承载无边框 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));
  }
}

最终看起来像这样:

【讨论】:

    【解决方案2】:

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

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

    使用FontFamilyGetLineSpacing()GetCellAscent() 方法计算基线的位置,然后向下移动用于绘制线条的Pen 的大小。
    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;
            }
        }
    }
    

    看起来像这样:


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

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

    【讨论】:

      猜你喜欢
      • 2015-06-25
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 2021-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-16
      相关资源
      最近更新 更多