.net 自定义控件(groupbox、picturebox、label)-鼠标输入时,内部消失

.net 自定义控件(groupbox、picturebox、label)-鼠标输入时,内部消失,.net,vb.net,groupbox,.net,Vb.net,Groupbox,对不起,这个标题很混乱,这是我的问题。我有一个自定义的GroupBox,里面是一个自定义的picturebox和标签 问题是,每当鼠标进入GroupBox时,当我启动表单应用程序时,我的标签的字体颜色变为黑色,而我的图片框似乎“消失了”。我不知道为什么会这样 分组框: Class GhostGroupBox Inherits ThemeControl154 Sub New() MyBase.New() SetStyle(ControlStyles

对不起,这个标题很混乱,这是我的问题。我有一个自定义的GroupBox,里面是一个自定义的picturebox和标签

问题是,每当鼠标进入GroupBox时,当我启动表单应用程序时,我的标签的字体颜色变为黑色,而我的图片框似乎“消失了”。我不知道为什么会这样

分组框:

Class GhostGroupBox
    Inherits ThemeControl154

    Sub New()
        MyBase.New()
        SetStyle(ControlStyles.ResizeRedraw, True)
        SetStyle(ControlStyles.ContainerControl, True)
        DoubleBuffered = True
        BackColor = Color.Transparent
    End Sub

    Protected Overrides Sub ColorHook()

    End Sub

    Protected Overrides Sub PaintHook()
        G.Clear(Color.FromArgb(60, 60, 60))
        Dim asdf As HatchBrush
        asdf = New HatchBrush(HatchStyle.DarkDownwardDiagonal, Color.FromArgb(35, Color.Black), Color.FromArgb(0, Color.Gray))
        G.FillRectangle(New SolidBrush(Color.FromArgb(60, 60, 60)), New Rectangle(0, 0, Width, Height))
        asdf = New HatchBrush(HatchStyle.LightDownwardDiagonal, Color.DimGray)
        G.FillRectangle(asdf, 0, 0, Width, Height)
        G.FillRectangle(New SolidBrush(Color.FromArgb(230, 20, 20, 20)), 0, 0, Width, Height)
        G.FillRectangle(New SolidBrush(Color.FromArgb(70, Color.Black)), 1, 1, Width - 2, Me.CreateGraphics.MeasureString(Text, Font).Height + 8)

        G.DrawLine(New Pen(Color.FromArgb(90, 90, 90)), 1, Me.CreateGraphics.MeasureString(Text, Font).Height + 8, Width - 2, Me.CreateGraphics.MeasureString(Text, Font).Height + 8)

        DrawBorders(Pens.Black)
        DrawBorders(New Pen(Color.FromArgb(90, 90, 90)), 1)
        G.DrawString(Text, Font, Brushes.White, 5, 5)
    End Sub
End Class
Label&PictureBox(相同的代码,仅继承各自的):


有人能看出来是怎么回事吗?我试着对控制盒的OnMouseMove进行注释,但没有修复它。我也没有为ControlBox设置任何事件。

如果没有工作代码,很难说,我有两个建议:

  • OnMouseMove
    中的
    Invalidate
    更改为
    Invalidate(True)
    以便
    GroupBox
    的子项也得到刷新。子控件可能无法获取绘制消息

  • 对于透明控件,您应该在
    OnHandleCreated
    中使用
    SetStyle(ControlStyles.SupportsTransparentBackColor或ControlStyles.UserPaint,True)
    ,而不是在
    CreateParams
    中设置
    ExStyle
    。Plus
    &H20
    表示
    WS\u EX\u TRANSPARENT
    ,而在构造函数中将控件设置为不透明


  • 我还有另一个建议-克隆您的项目并尝试在那里简化您的代码,直到它仍然存在问题,但足够通用,您可以在这里发布它。另外,您没有描述所有自定义控件都应该做什么。除此之外,您是否尝试过以下方法来减少闪烁

    SendMessage(Me.Handle, WM_SETREDRAW, False, 0) ' Turn OFF UI updates
    

    我在我的项目中使用它作为自定义下拉控件,效果很好

    根据我的经验,
    双缓冲
    是没用的

    要使
    SendMessage
    可用,您需要从
    user32
    导入它:

    Private Const WM_SETREDRAW As Integer = &HB
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    

    您可以在
    PaintHook
    (第一行)内的任何处理之前关闭UI更新,并在所有处理完成后重新打开它。还需要在发送消息(…True…)之后调用
    Me.Refresh()
    ,否则您将无法获得任何更新。

    Visual Basic不是标记,VBA是Visual Basic应用程序,所以我认为可能就是它。很抱歉,我已经删除了标签,因为我现在重新阅读了VBA是什么。首先,欢迎使用堆栈溢出!我更新了OP,之前GroupBox的代码是错误的,而不是我使用的代码。我将
    OnMouseMove
    添加到正确的部分,因为它不存在,并使其
    Invalidate(True)
    。这似乎在大多数情况下都有效,但并不是100%可靠。第二个选项使Visual Basic 2012 Express完全崩溃。因此,这将暂时起作用,但我将等待接受此答案,看看是否有其他人有更好的解决方案。仅供参考,当我将鼠标放在其中时,您的解决方案使其看起来快速闪烁,并且当鼠标离开时,大多数控件都消失了。闪烁通常意味着未启用双缓冲。我看到你打开了双缓冲,但我可以推荐好的老式设置方式吗?双缓冲仅使用UserPaint style标志激活,不能设置。另一方面,SetStyle只应在创建句柄后调用,所以构造函数不是它的好位置。手工制作?对于没有工作代码的MouseLeave部分,我真的说不出来。对不起,你能告诉我需要包括哪些代码吗?我对设计和诸如此类的东西很在行,对你刚写的东西不太了解。
    sendmages没有声明。
    我把它放在了
    双缓冲区下,对吗?很抱歉,我对这类内容了解不多。@DannyF247:您需要用SendMessage行包装自定义绘图,分别关闭和打开UI更新。我用新信息更新了答案。我完全按照你说的做了,在PaintHook开始时关闭更新,在PaintHook结束时重新启用,然后执行了
    Me.Refresh()
    ,但它仍然闪烁:/Any suggestions?创建一个POC(概念验证)项目并尝试在那里复制。如果可以,在这里发表,也许有人会看一看。这是常规调试/故障排除过程的一部分,也是您作为程序员的责任。
    SendMessage(Me.Handle, WM_SETREDRAW, True, 0) ' Turn ON UI updates
    
    Private Const WM_SETREDRAW As Integer = &HB
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer