5

I'm a newbie, and recently I've asked this question, where it taught me to have my best option for TextBox's bottom border, that prevents flickering/tearing - resulted by drawn graphics.

Now my problem is how to have margin/paddings for the text/string inside the textbox, here's the code:

using System.Drawing;
using System.Windows.Forms;

namespace main.Classes.CustomControls {

    class TextBoxMaterial : TextBox {
        public TextBoxMaterial() {
            this.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.Controls.Add(new Label() {
                Height = 2,
                Dock = DockStyle.Bottom,
                BackColor = Color.Gray,
            });
        }
    }
}

Currently textbox:

enter image description here

What I need to have:

enter image description here

Community
  • 1
  • 1
Aesthetic
  • 763
  • 1
  • 14
  • 31

2 Answers2

3

You can set left padding and right padding for text of TextBox by sending an EM_SETMARGINS. You also can set AutoSize property of the TextBox to false to be able to change the height of control. Here is the result:

enter image description here

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
public class ExTextBox : TextBox
{
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hwnd, int msg,
        int wParam, int lParam);
    private const int EM_SETMARGINS = 0xd3;
    private const int EC_RIGHTMARGIN = 2;
    private const int EC_LEFTMARGIN = 1;
    private int p = 10;
    public ExTextBox()
        : base()
    {
        var b = new Label { Dock = DockStyle.Bottom, Height = 2, BackColor = Color.Gray };
        var l = new Label { Dock = DockStyle.Left, Width = p, BackColor = Color.White };
        var r = new Label { Dock = DockStyle.Right, Width = p, BackColor = Color.White };
        AutoSize = false;
        Padding = new Padding(0);
        BorderStyle = System.Windows.Forms.BorderStyle.None;
        Controls.AddRange(new Control[] { l, r, b });
    }
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        SetMargin();
    }
    private void SetMargin()
    {
        SendMessage(Handle, EM_SETMARGINS, EC_RIGHTMARGIN, p << 16);
        SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN, p);
    }
}

To know what the role of right label is, try not adding it to the control, then write a long text to TextBox and go to the end of text by arrow keys and again back to the beginning using arrow keys.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • I was about to ask a new question, but it will be a duplicate if I do, because this has been already answered here in this question [http://stackoverflow.com/questions/4902565/watermark-textbox-in-winforms/36534068] I like your answer there, but using it in my code with this answer for text padding gives me: http://i.imgur.com/bFToAiR.png .. If it's allowed to ask a new question for this I would, but it could be marked as duplicate, please help! Thank you. – Aesthetic Jul 19 '16 at 13:56
  • 1
    You can change the rectangle which you want to draw text in. `var rect = this.ClientRectangle; rect.Inflate(-p,0);` It creates a rectangle width deflating it's width. For example `(0,0,100,20)` will change to `10,0,80,20` . Then use it for drawing string: `TextRenderer.DrawText(g, this.Hint, this.Font, rect, SystemColors.GrayText, this.BackColor, TextFormatFlags.Top | TextFormatFlags.Left | TextFormatFlags.NoPadding);` Let me know if you have any problem applying the codes :) – Reza Aghaei Jul 19 '16 at 16:33
  • To know what the role of right label is, try to not adding it to the control, then write a long text to TextBox and go to the end of text by arrow keys and again back to the beginning using arrow keys. – Reza Aghaei Jul 19 '16 at 17:08
1

I think you will have to inherit from UserControl rather than from TextBox and add a TextBox to your UserControl. Code below is by no means complete but should show you what I'm talking about

public partial class TextBoxMaterial : UserControl
{
    public TextBoxMaterial()
    {
        InitializeComponent();

        this.Controls.Add(new Label()
        {
            Height = 2,
            Dock = DockStyle.Bottom,
            BackColor = Color.Gray,
        });

        this.Controls.Add(new TextBox()
        {
            Left = 10,
            Width = this.Width - 20,
            BackColor = this.BackColor,
            BorderStyle = BorderStyle.None,
         });
    }
}
RobCroll
  • 2,571
  • 1
  • 26
  • 36
  • Considering this to be of my last resort, was thinking about the same thing, but still hoping I could just have a TextBox with text padding. On my previous question, a user commented this http://stackoverflow.com/questions/37947251/numericupdown-with-unit-custom-control-field-padding/37949670#37949670 , telling me it's possible to create padding on text. – Aesthetic Jul 19 '16 at 04:52
  • Didn't take a close look but I know padding text and alike in Winforms is always problematic as users do weird stuff that is hard to second guess. – RobCroll Jul 19 '16 at 04:59
  • 1
    @Yawz Yes, it's possible. I posted an answer for you :) – Reza Aghaei Jul 19 '16 at 06:26