如何在继承的TextBox中保留Font?

问题描述 投票:0回答:5

我使用以下代码来获取未绘制边框的 TextBox:

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

我似乎错过了 OnPaint() 内部的某些内容,因为我的字体不再是文本框的默认字体(也许我必须覆盖另一个事件)。

检查 CustomTextBox.Font 属性时,它显示默认的“Microsoft SansSerif in 8,25”,但是当在我的文本框中输入文本时,字体肯定看起来更大、更粗。

希望你能帮助我!

问候,

创新

[编辑]

我应该提到,如果我不重写 OnPaint,我的 CustomTextBox 的字体是正确的。仅当覆盖 OnPaint 时,我的字体不正确(输入文本时字体更大并且看起来是粗体)。 所以我想我必须做一些事情来在 OnPaint 内正确初始化字体(但 ATM 我不知道如何做到这一点)。

c# .net winforms user-controls
5个回答
6
投票

如果尚未创建文本框的句柄,则不要调用 SetStyle,并且它永远不会更改为“大粗体”字体:

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

2
投票

如果没有显式设置 TextBox 的字体,它会从其父级和祖先获取字体,因此如果 TextBox 位于 Panel 上,它将从该 Panel 或父 Form 获取字体。


2
投票

有两个选项供您查看... 在我的基类中,我强制使用只读字体定义...与其他控件类似,因此具有该类的其他开发人员无法更改它 --- PERIOD。

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

第二个选项,我实际上没有使用是在表单的序列化过程中。我不能相信,也不记得我在这个论坛的其他地方找到的,但也可能有帮助。显然,通过隐藏序列化可见性,它不会强制每个控件的属性(在本例中,适用于您的字体)

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

HTH


0
投票

根据

这个答案
,在文本框上使用SetStyle总是会弄乱绘画。

但是...有什么理由不能简单地将其

BorderStyle
设置为
None
吗?

如果需要,您甚至可以修改

BorderStyle
,使其默认值为
None
,如下所示:

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

0
投票

我想这会解决你的问题

  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();
}
© www.soinside.com 2019 - 2024. All rights reserved.