文本框的OnPaint方法没有被调用?

4
我使用了以下代码创建文本框,但是在任何情况下都没有触发绘画方法。你能否建议一个触发OnPaint()的解决方案?
public class MyTextBox : TextBox
{
    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        base.OnPaintBackground(pevent);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        ControlPaint.DrawBorder(e.Graphics,this.Bounds, Color.Red,ButtonBorderStyle.Solid);
        base.OnPaint(e);
    }

    protected override void OnTextChanged(EventArgs e)
    {
        this.Invalidate();
        this.Refresh();
        base.OnTextChanged(e);
    }
}

2
你调试过它没有被触发吗?你的 DrawBorder 调用可能是无用的,因为你在之后才调用了 base.OnPaint()。所以 TextBox 会再次绘制自己,覆盖掉你之前绘制的内容。 - René Vogt
3个回答

22

默认情况下,TextBox 不会自动调用 OnPaint 方法。除非您将其注册为自绘控件,方法是调用:

SetStyle(ControlStyles.UserPaint, true);

例如,来自您的MyTextBox构造函数。


5
如果这个回答解决了你的问题,请标记它为答案,以帮助未来有类似问题的用户。 - Jarrett Robertson
1
这解决了触发事件的问题,但搞乱了文本框的操作方式。 - KodFun
这可能会调用OnPaint,但现在它被系统以微小的字体和微小的插入符号绘制,我的OnPaint方法被覆盖。切换到RichTextBox允许我自己绘制,但插入符仍由系统绘制。 - Bip901
就像René Vogt所提到的那样,Paint Event不受默认TextBox的支持,使用SetStyle(ControlStyles.UserPaint, true)也不可行。 在我看来,为了自定义TextBox,最好创建一个用户控件(派生自TextBox)以实现此目的。 虽然需要一些工作和时间,但它将比尝试修改基本控件更有效,并且性能更好。 - user12761381

4
您需要在您的OnPaint中切换调用。
protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    ControlPaint.DrawBorder(e.Graphics, this.Bounds, Color.Red, ButtonBorderStyle.Solid);
}

base.OnPaint()绘制常规的TextBox。如果在base调用之前调用DrawBorder,则它将被基本实现覆盖。


但是根据文档TextBox不支持Paint事件:

此 API 支持产品基础结构,不建议直接从您的代码中使用。
控件重新绘制时会发生此事件。该事件对于此类不相关。

因此,Ben Jackon的答案应该解决了这个问题。


没问题。我在问的是触发OnPaint方法。 - Venkatesh Ks
我在询问触发了 OnPaint 方法,因为这个方法没有被触发。 - Venkatesh Ks
@VenkateshKs 好的,Ben已经得到了答案。我把这个帖子留下来,因为调用顺序在你的代码中仍然是一个相关的问题。 - René Vogt

1
我所做的是在窗口接收到WM_PAINT消息后创建图形对象。

C#

protected override void WndProc(ref Message m)
{
    base.WndProc(m);
    switch (m.Msg)
    {
        case WM_PAINT:
            BackgroundText();
            break;
    }
}

private void BackgroundText()
{
    if (DesignMode)
    {
        using (Graphics G = CreateGraphics())
        {
            TextRenderer.DrawText(G, "Project No.", new Font("Microsoft Sans Serif", 8.25), new Point(3, 1), Color.FromArgb(94, 101, 117));
        }
        return;
    }
    if (string.IsNullOrEmpty(Text))
    {
        using (Graphics G = CreateGraphics())
        {
            Color tColor = FindForm.ActiveControl == this ? Color.FromArgb(94, 101, 117) : SystemColors.Window;
            TextRenderer.DrawText(G, "Project No.", new Font("Microsoft Sans Serif", 8.25), new Point(3, 1), tColor);
        }
    }
}

VB.NET

Protected Overrides Sub WndProc(ByRef m As Message)
    MyBase.WndProc(m)
    Select Case m.Msg
        Case WM_PAINT
            BackgroundText()
    End Select
End Sub

Private Sub BackgroundText()
    If DesignMode Then
        Using G As Graphics = CreateGraphics()
            TextRenderer.DrawText(G, "Project No.", New Font("Microsoft Sans Serif", 8.25), New Point(3, 1), Color.FromArgb(94, 101, 117))
        End Using
        Return
    End If
    If String.IsNullOrEmpty(Text) Then
        Using G As Graphics = CreateGraphics()
            Dim tColor As Color = If(FindForm.ActiveControl Is Me, Color.FromArgb(94, 101, 117), SystemColors.Window)
            TextRenderer.DrawText(G, "Project No.", New Font("Microsoft Sans Serif", 8.25), New Point(3, 1), tColor)
        End Using
    End If
End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接