Inno
Inno

Reputation: 2567

How to keep Font in inherited TextBox?

I'm using the following code to get a TextBox that is not drawing its borders:

public partial class CustomTextBox : TextBox
{
    public CustomTextBox()
    {
        InitializeComponent();
        SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        int borderWidth = 1;

        ControlPaint.DrawBorder(e.Graphics, e.ClipRectangle,
            Color.Transparent, borderWidth, ButtonBorderStyle.Solid,
            Color.Transparent, borderWidth, ButtonBorderStyle.Solid,
            Color.Transparent, borderWidth, ButtonBorderStyle.Solid,
            Color.Transparent, borderWidth, ButtonBorderStyle.Solid);
    }
}

I seem to miss something inside of OnPaint() because my Font is not the default Font for a textBox anymore (perhaps I have to override another event).

When checking CustomTextBox.Font property it shows me the default "Microsoft SansSerif in 8,25" but when typing text into my textBox the Font definitely looks bigger and bold.

Hope you can help me!

Regards,

inno

[EDIT]

I should mention that if I don't override OnPaint the Font of my CustomTextBox is correct. Only when overriding OnPaint my Font is incorrect (when typing text the font is bigger and seems to be bold). So I think I have to do something to initialize the font correctly inside of OnPaint (but ATM I have no idea how to do this).

Upvotes: 4

Views: 3212

Answers (5)

Amro Omran
Amro Omran

Reputation: 1

I think this will solve your problem

  protected override void OnGotFocus(EventArgs e)
{
    base.OnGotFocus(e);

    SetMultiline(true);
    SetFontFamilyAndStyle(Font.FontFamily.Name);
}

public void SetFontFamilyAndStyle(string fontFamilyName)
{
    // Get the existing font style
    FontStyle currentFontStyle = Font.Style;

    // Create a new font with the specified font family and the existing font style
    Font newFont = new Font(fontFamilyName, Font.Size, currentFontStyle);

    // Set the new font
    SendMessage(Handle, WM_SETFONT, newFont.ToHfont(), (IntPtr)1);
    Font = newFont;

    // Redraw the control
    Invalidate();
}
private const int WM_SETFONT = 0x30;
private const int EM_SETOPTIONS = 0x2003;
private const int ECOOP_SET = 0x0002;

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

public void SetMultiline(bool multiline)
{
    int options = multiline ? ECOOP_SET : 0;
    SendMessage(Handle, EM_SETOPTIONS, (IntPtr)options, IntPtr.Zero);
    Multiline = multiline;
    // Redraw the control
    Invalidate();
}

Upvotes: 1

Vedran
Vedran

Reputation: 11039

Don't call SetStyle if the handle for the textbox is not yet created, and it won't ever change to that 'big bold' font:

if (IsHandleCreated)
{
     SetStyle(ControlStyles.UserPaint, true);
}

Upvotes: 6

DRapp
DRapp

Reputation: 48169

Two options for you to look at... In my base-class, I'm forcing a read-only font definition... similar for other controls, so other developers with the class can't change it --- PERIOD.

[ReadOnly(true)]
public override Font Font
{
    get
    {
        return new Font("Courier New", 12F, FontStyle.Regular, GraphicsUnit.Point);
    }
}

Second option, and I did not actually use is during the serialization of the form. I can't take credit, nor remember where I found elsewhere in this forum, but may help too. Apparenty, by hidding the serialization visibility, it doesn't FORCE each individual control's property (in this case, apply for your font) [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

HTH

Upvotes: 2

takrl
takrl

Reputation: 6482

Using SetStyle on a Textbox will always mess up the painting, according to this answer.

However ... is there any reason why you can't simply set it's BorderStyle to None?

If you need to, you can even modify the BorderStyle so that it's default value is None, like this:

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

namespace MyControls
{
  // Apply ToolboxBitmap attribute here
  public class CustomTextBox : TextBox
  {
    public CustomTextBox()
    {
      BorderStyle = BorderStyle.None;
    }

    [DefaultValue(typeof(System.Windows.Forms.BorderStyle),"None")]
    public new BorderStyle BorderStyle
    {
      get { return base.BorderStyle; }
      set { base.BorderStyle = value; }
    }
  }
}

Upvotes: 0

Tommy Carlier
Tommy Carlier

Reputation: 8159

If you don't explicitely set the font of a TextBox, it gets its font from its parent and ancestors, so if the TextBox is on a Panel, it gets its font from that Panel, or from the parent Form.

Upvotes: 2

Related Questions