【问题标题】:Maintain button forecolor when disabled禁用时保持按钮前景色
【发布时间】:2017-11-26 06:49:27
【问题描述】:

我的 winform 应用程序中有一个按钮。问题是当我禁用按钮时,前景色变成绿色。有没有办法保持前色黑色,即使它被禁用?我从过去的 SO 问题中尝试了许多解决方案,现在用谷歌搜索了一段时间。但解决方案要么在 c# 中(我转换了它们,但仍然没有运气),要么创建一个自定义按钮控件。有什么解决办法吗?

【问题讨论】:

标签: vb.net button disabled-control


【解决方案1】:

我遇到了类似的问题。按钮不接受.ForColor 分配的原因(如果我没记错的话)与正在重绘和重绘它的背景事件有关。我还没有深入了解“细节”,但我得到的要点是(据我目前发现)解决颜色的唯一方法是在绘画事件中。

基本上,您可以在 Extension 中处理颜色变化,而不是使用 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

【讨论】:

  • @Aousafrashid 代码编辑:我意识到每次调用 .Disable 时我都在添加处理程序(多次将相同的处理程序添加到可能相同的按钮)并且我没有为@987654328 添加处理程序@。代码现在应该没有这些问题。
猜你喜欢
  • 2013-03-14
  • 2014-11-06
  • 2021-11-19
  • 2020-01-01
  • 2016-12-11
  • 2020-07-06
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多