禁用时保持按钮前景色
Maintain button forecolor when disabled
我的 winform 中有一个按钮 app.The 问题是当我禁用该按钮时,前景颜色变为绿色 - ish.Is 有一种方法可以使前景颜色保持黑色,即使它被禁用了? ?我从过去的 SO 问题中尝试了许多解决方案,安静地搜索了一段时间 now.But 解决方案要么在 c# 中(我转换了它们,但仍然没有运气),要么创建一个自定义按钮控件。有什么解决办法吗?
我遇到了类似的问题。按钮不接受 .ForColor
分配的原因(如果我没记错的话)与重绘和重绘它的背景事件有关。我还没有完全了解 "nitty-gritty",但我得到的要点是(据我到目前为止所发现的)解决颜色的唯一方法是在绘画事件中。
基本上,您可以在扩展中处理颜色变化,而不是使用 Button.Enabled = False
,您可以这样称呼它:
btnNext.Enable
btnPrevious.Disable
您需要做的就是向您的项目添加一个模块(如下),所有按钮都将具有 .Enable
和 .Disable
扩展名。
这是模块:
Module Extensions
<System.Runtime.CompilerServices.Extension()>
Public Sub Enable(ByVal btn As Button)
If btn.Tag = Nothing Then ' << This ensures we only add the handler once.
AddHandler btn.EnabledChanged, AddressOf btn_EnabledChanged
AddHandler btn.Paint, AddressOf btn_Paint
End If
btn.Enabled = True
End Sub
<System.Runtime.CompilerServices.Extension()>
Public Sub Disable(ByVal btn As Button)
If btn.Tag = Nothing Then ' << This ensures we only add the handler once.
AddHandler btn.EnabledChanged, AddressOf btn_EnabledChanged
AddHandler btn.Paint, AddressOf btn_Paint
End If
btn.Enabled = False
End Sub
Private Sub btn_EnabledChanged(sender As Object, e As System.EventArgs)
Dim btn As Button = DirectCast(sender, Button)
If sender.enabled = False Then
btn.ForeColor = Color.Black
Else
btn.ForeColor = Color.Black
End If
End Sub
Private Sub btn_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs)
'Dim TextForBtn As String = "" ' << we don't use a variable because that would only be useful if we could reassign to the .Text property, but that just raises the Paint Event again causing a infinite loop.
Dim btn As Button = DirectCast(sender, Button)
If btn.Text > " " Then
btn.Tag = btn.Text ' << this allows us to redraw the text, the one issue however is the .Text property is empty from here on out.
'TextForBtn = btn.Text ' << this is part of the failed idea of using a variable and reassigning to the .Text property.
End If
btn.Text = String.Empty ' << make sure Text is not written on button as well as rendered below
Dim flags As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter Or TextFormatFlags.WordBreak 'center the text
TextRenderer.DrawText(e.Graphics, btn.Tag.ToString, btn.Font, e.ClipRectangle, btn.ForeColor, flags) ' << TextForBtn was replaced with btn.Tag.ToString in the second parameter
'btn.Text = TextForBtn ' << this caused an infinite loop necessitating the use of the .Tag property.
End Sub
End Module
我的 winform 中有一个按钮 app.The 问题是当我禁用该按钮时,前景颜色变为绿色 - ish.Is 有一种方法可以使前景颜色保持黑色,即使它被禁用了? ?我从过去的 SO 问题中尝试了许多解决方案,安静地搜索了一段时间 now.But 解决方案要么在 c# 中(我转换了它们,但仍然没有运气),要么创建一个自定义按钮控件。有什么解决办法吗?
我遇到了类似的问题。按钮不接受 .ForColor
分配的原因(如果我没记错的话)与重绘和重绘它的背景事件有关。我还没有完全了解 "nitty-gritty",但我得到的要点是(据我到目前为止所发现的)解决颜色的唯一方法是在绘画事件中。
基本上,您可以在扩展中处理颜色变化,而不是使用 Button.Enabled = False
,您可以这样称呼它:
btnNext.Enable
btnPrevious.Disable
您需要做的就是向您的项目添加一个模块(如下),所有按钮都将具有 .Enable
和 .Disable
扩展名。
这是模块:
Module Extensions
<System.Runtime.CompilerServices.Extension()>
Public Sub Enable(ByVal btn As Button)
If btn.Tag = Nothing Then ' << This ensures we only add the handler once.
AddHandler btn.EnabledChanged, AddressOf btn_EnabledChanged
AddHandler btn.Paint, AddressOf btn_Paint
End If
btn.Enabled = True
End Sub
<System.Runtime.CompilerServices.Extension()>
Public Sub Disable(ByVal btn As Button)
If btn.Tag = Nothing Then ' << This ensures we only add the handler once.
AddHandler btn.EnabledChanged, AddressOf btn_EnabledChanged
AddHandler btn.Paint, AddressOf btn_Paint
End If
btn.Enabled = False
End Sub
Private Sub btn_EnabledChanged(sender As Object, e As System.EventArgs)
Dim btn As Button = DirectCast(sender, Button)
If sender.enabled = False Then
btn.ForeColor = Color.Black
Else
btn.ForeColor = Color.Black
End If
End Sub
Private Sub btn_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs)
'Dim TextForBtn As String = "" ' << we don't use a variable because that would only be useful if we could reassign to the .Text property, but that just raises the Paint Event again causing a infinite loop.
Dim btn As Button = DirectCast(sender, Button)
If btn.Text > " " Then
btn.Tag = btn.Text ' << this allows us to redraw the text, the one issue however is the .Text property is empty from here on out.
'TextForBtn = btn.Text ' << this is part of the failed idea of using a variable and reassigning to the .Text property.
End If
btn.Text = String.Empty ' << make sure Text is not written on button as well as rendered below
Dim flags As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter Or TextFormatFlags.WordBreak 'center the text
TextRenderer.DrawText(e.Graphics, btn.Tag.ToString, btn.Font, e.ClipRectangle, btn.ForeColor, flags) ' << TextForBtn was replaced with btn.Tag.ToString in the second parameter
'btn.Text = TextForBtn ' << this caused an infinite loop necessitating the use of the .Tag property.
End Sub
End Module