关于textbox控件的背景,我问了几次,为什么没人回答呢????

时间:2021-07-20 00:58:08
我想让它可加入背景图片,和让它的背景可透明,怎么办??
就是重做控件也可以,就该如何做呢????继承textbox,再.....???

12 个解决方案

#1


继承后。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//下面添加你重画的代码。
}

#2


怎么最近来是有人喜欢使用OnPaint去做,或者说喜欢使用OnXXX去做呢?
好像怎么制止也不行。

请尽量首先使用Paint事件,如果不行再考虑用别的方法比如OnPaint。

Private Sub TextBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles TextBox1.Paint
    Dim t As TextBox
    t = CType(sender, TextBox)
    e.DrawImage(t.Image, ...)  ' 慢慢填吧……
    ' ....
End Sub

当然你也可以继承TextBox控件,创作自己的控件,稍微方便一点点。

#3


能写一段简明的代码吗?只要求出现的textbox控件有图像背景就行,我试了许多次都不行!!

你上面的代码最起码t.Image就是不可能的它没有这个属性,backgroundimage也不行,没有效果!!继承TextBox控件也行啊,但也许有关键过后语句我没在加上,却又不知道,没办法,帮一下,版主!
starw2001@sina.com

#4


to  sumtec(Psydian) :
很同意你的观点,我也发现了这个问题。

#5


不好意思,你可以用BackgroundImage来做。

#6


我看了一下,用BackGroundImage也有问题的。默认情况下TextBox不会产生paint事件。
只能呢着一下看有没有其他的第三方控件。这也是.NET的一个Bug。

#7


在网页中可以的,在这里没有理由做不出的,不论用什么办法,请高手们再试试看!!

当然我最希望的是能获得透明背景,其次是编一个较规范的继承textbox控件,能把背景图做为一个属性也行,最后才是用诸如paint等的手段来重绘控件,

但不管怎样,现在是以把textbox从单调的背景色彩中拉出来为目地!!

#8


不好意思,失职啊!我没有仔细查TextBox的成员,对于TextBox,本身已经屏蔽掉Paint事件,所以必须要从TextBox那里继承一个新的控件才行。此外我试了一下,发现如果要做这个效果还是有一定难度的!目前正在试。

此外,我可以告诉你为什么BackgroundImage没有用,OnPaint也没有用:因为TextBox负责界面方面的代码并不是通过一般的OnPaint来完成的。如果你要让OnPaint能够发挥效用,你就必须要在新控件的Sub New()里面,在InitializeComponent()这句话后面添加:

        setstyle(ControlStyles.UserPaint, True)
        setstyle(ControlStyles.AllPaintingInWmPaint, True)

另外,也有人问我为什么不要用OnXXX而应该尽量直接使用XXX事件,我的回答如下:


是这样的,OnPaint/Paint一般类似于这样的:

' 基类的OnPaint,如果标准的话,大概是这样子的:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    ' 最基本的行为:比如用BackColor填充背景等。
    ...
    ' 产生事件:
    RaiseEvent Paint(Me, pevent)
End Sub

' 某个标准控件比如Label继承这个基类,如果是标准形式:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    ' 调用基类OnPaint,或者说实现基类的行为。
    MyBase.OnPaint(pevent)
    ' 这里写的是某个控件收到WM_Paint之后应该做的事情,比如说画一个边框等。
    ...
End Sub

' 但是有的时候,某些控件在一些特定的情况下并不一定希望实现标准的行为。
' 比如说一个TextBox,他就不希望产生Paint事件,因为这样的话,
' 用户的代码可能会把画上去的字给覆盖掉。或者说有时候不希望有标准的行为,
' 于是可能会产生某种分支:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    If ... Then
        ' 实现标准的行为:
        MyBase.OnPaint(pevent)
    Else
        ' 自定义的行为:
        ...
    End If
End Sub

有时候某些控件甚至会屏蔽基类的行为,或者说不希望出现基类所实现的那种行为,我们甚至可能会根本不调用MyBase.OnXXX。

我们有时候不清楚父类有什么行为在里面,如果我们贸然修改OnPaint比如说没有调用MyBase.OnPaint,那么就可能产生意想不到的效果,比如不会产生Paint事件、或者没有对消息队列做出正确地反应、或者因为某些执行顺序不正确而不时地出现错误等等。因此修改OnXXX应当小心谨慎,不然你写出来的控件就可能隐含有某种不易察觉的Bug。

但是Paint事件就不一样了,这个是设计者预留给用户写代码的地方,或者说本来设计者的用意就是让你在这里做你想做的事情,那么你做什么事情都应该不会出错。如果出错了,那应该是设计者考虑得不够周详。一般来说在这里写代码是相当安全的。

#9


我调用了setstyle设置,但在进行输入时,会把输入行刷成白色,还有什么别的办法吗?,还是只能这样了,设置透明和重绘背景都可以,但一输入就不是那么回事了??
难道真没有办法了吗??

引用:(sumtec:目前正在试。)

试好了吗??

#10


试了老半天,没有办法简单的解决这个问题。突然发现如果你修改UserPaint和AllPaintInWmPaint的话,字体就会不正确。

目前只能够做到将图和字都显示出来,但是如果输入的内容超过文本框的长度就不能够很好的定位了,应该说根本不知道怎么才能够简单的进行定位。我觉得似乎应该放弃从TextBox这方面去考虑了。

    Private busy As Boolean = False
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Dim g As Graphics
        g = Me.CreateGraphics
        MyBase.WndProc(m)
        If busy OrElse (Me.BackgroundImage Is Nothing) Then Return
        busy = True
        g.DrawImageUnscaled(Me.BackgroundImage, New Point(0, 0))
        g.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), -1, 1)
        busy = False
    End Sub

这就是目前的效果了。其他的都不用改。
帮不了你啦!要看Saucer等前辈了。
(要不用其他东西算了?或者如果你可以接受画一个半透明的背景,那我倒是有办法的。)

#11


也行,你帖也来我试试,或发到我的邮箱中
谢谢!!

starw2001@sina.com

上面的代码,我回去试试!!!

#12


运行很慢,可能不是我机器的问题,Saucer等前辈在哪里???

谢谢 sumtec 版主的回答,我本以为这不是个很难的问题呢,看来只好等了...(请接分)

#1


继承后。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//下面添加你重画的代码。
}

#2


怎么最近来是有人喜欢使用OnPaint去做,或者说喜欢使用OnXXX去做呢?
好像怎么制止也不行。

请尽量首先使用Paint事件,如果不行再考虑用别的方法比如OnPaint。

Private Sub TextBox1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles TextBox1.Paint
    Dim t As TextBox
    t = CType(sender, TextBox)
    e.DrawImage(t.Image, ...)  ' 慢慢填吧……
    ' ....
End Sub

当然你也可以继承TextBox控件,创作自己的控件,稍微方便一点点。

#3


能写一段简明的代码吗?只要求出现的textbox控件有图像背景就行,我试了许多次都不行!!

你上面的代码最起码t.Image就是不可能的它没有这个属性,backgroundimage也不行,没有效果!!继承TextBox控件也行啊,但也许有关键过后语句我没在加上,却又不知道,没办法,帮一下,版主!
starw2001@sina.com

#4


to  sumtec(Psydian) :
很同意你的观点,我也发现了这个问题。

#5


不好意思,你可以用BackgroundImage来做。

#6


我看了一下,用BackGroundImage也有问题的。默认情况下TextBox不会产生paint事件。
只能呢着一下看有没有其他的第三方控件。这也是.NET的一个Bug。

#7


在网页中可以的,在这里没有理由做不出的,不论用什么办法,请高手们再试试看!!

当然我最希望的是能获得透明背景,其次是编一个较规范的继承textbox控件,能把背景图做为一个属性也行,最后才是用诸如paint等的手段来重绘控件,

但不管怎样,现在是以把textbox从单调的背景色彩中拉出来为目地!!

#8


不好意思,失职啊!我没有仔细查TextBox的成员,对于TextBox,本身已经屏蔽掉Paint事件,所以必须要从TextBox那里继承一个新的控件才行。此外我试了一下,发现如果要做这个效果还是有一定难度的!目前正在试。

此外,我可以告诉你为什么BackgroundImage没有用,OnPaint也没有用:因为TextBox负责界面方面的代码并不是通过一般的OnPaint来完成的。如果你要让OnPaint能够发挥效用,你就必须要在新控件的Sub New()里面,在InitializeComponent()这句话后面添加:

        setstyle(ControlStyles.UserPaint, True)
        setstyle(ControlStyles.AllPaintingInWmPaint, True)

另外,也有人问我为什么不要用OnXXX而应该尽量直接使用XXX事件,我的回答如下:


是这样的,OnPaint/Paint一般类似于这样的:

' 基类的OnPaint,如果标准的话,大概是这样子的:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    ' 最基本的行为:比如用BackColor填充背景等。
    ...
    ' 产生事件:
    RaiseEvent Paint(Me, pevent)
End Sub

' 某个标准控件比如Label继承这个基类,如果是标准形式:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    ' 调用基类OnPaint,或者说实现基类的行为。
    MyBase.OnPaint(pevent)
    ' 这里写的是某个控件收到WM_Paint之后应该做的事情,比如说画一个边框等。
    ...
End Sub

' 但是有的时候,某些控件在一些特定的情况下并不一定希望实现标准的行为。
' 比如说一个TextBox,他就不希望产生Paint事件,因为这样的话,
' 用户的代码可能会把画上去的字给覆盖掉。或者说有时候不希望有标准的行为,
' 于是可能会产生某种分支:
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
    If ... Then
        ' 实现标准的行为:
        MyBase.OnPaint(pevent)
    Else
        ' 自定义的行为:
        ...
    End If
End Sub

有时候某些控件甚至会屏蔽基类的行为,或者说不希望出现基类所实现的那种行为,我们甚至可能会根本不调用MyBase.OnXXX。

我们有时候不清楚父类有什么行为在里面,如果我们贸然修改OnPaint比如说没有调用MyBase.OnPaint,那么就可能产生意想不到的效果,比如不会产生Paint事件、或者没有对消息队列做出正确地反应、或者因为某些执行顺序不正确而不时地出现错误等等。因此修改OnXXX应当小心谨慎,不然你写出来的控件就可能隐含有某种不易察觉的Bug。

但是Paint事件就不一样了,这个是设计者预留给用户写代码的地方,或者说本来设计者的用意就是让你在这里做你想做的事情,那么你做什么事情都应该不会出错。如果出错了,那应该是设计者考虑得不够周详。一般来说在这里写代码是相当安全的。

#9


我调用了setstyle设置,但在进行输入时,会把输入行刷成白色,还有什么别的办法吗?,还是只能这样了,设置透明和重绘背景都可以,但一输入就不是那么回事了??
难道真没有办法了吗??

引用:(sumtec:目前正在试。)

试好了吗??

#10


试了老半天,没有办法简单的解决这个问题。突然发现如果你修改UserPaint和AllPaintInWmPaint的话,字体就会不正确。

目前只能够做到将图和字都显示出来,但是如果输入的内容超过文本框的长度就不能够很好的定位了,应该说根本不知道怎么才能够简单的进行定位。我觉得似乎应该放弃从TextBox这方面去考虑了。

    Private busy As Boolean = False
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Dim g As Graphics
        g = Me.CreateGraphics
        MyBase.WndProc(m)
        If busy OrElse (Me.BackgroundImage Is Nothing) Then Return
        busy = True
        g.DrawImageUnscaled(Me.BackgroundImage, New Point(0, 0))
        g.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), -1, 1)
        busy = False
    End Sub

这就是目前的效果了。其他的都不用改。
帮不了你啦!要看Saucer等前辈了。
(要不用其他东西算了?或者如果你可以接受画一个半透明的背景,那我倒是有办法的。)

#11


也行,你帖也来我试试,或发到我的邮箱中
谢谢!!

starw2001@sina.com

上面的代码,我回去试试!!!

#12


运行很慢,可能不是我机器的问题,Saucer等前辈在哪里???

谢谢 sumtec 版主的回答,我本以为这不是个很难的问题呢,看来只好等了...(请接分)