Я столкнулся с проблемой кнопок в моем текущем проекте, «не выглядящих достаточно отключенными», на основании некоторых отзывов. Некоторые люди не сразу узнали, что некоторые кнопки отключены. Это в первую очередь потому, что цвет шрифта не изменился на достаточно светлый, чтобы его можно было заметить (я не уверен, как цвет автоматически определяется при отключении, но это не относится к делу). Вот как это выглядело:
Вот что привело меня к созданию расширения модуля, которое позволяет мне .Enable
или .Disable
любую кнопку легко и управляйте .ForeColor
. В итоге это выглядело так:
Я получил представление о том, как обрабатывать подобные изменения форматирования из этого сообщения , но были некоторые комментарии (и я убедился на собственном опыте), что лучше не связываться с событием Paint (я расскажу об этом подробнее и проиллюстрирую ниже.)
ER GO МОЙ ВОПРОС:
Есть ли разумная альтернатива использованию события Paint для управления форматированием кнопки?
Вот несколько ориентиры:
- Я не хочу создавать целый настраиваемый элемент управления, просто чтобы внести небольшие изменения цвета - мое расширение намного проще и может быть применено к любой кнопке.
- Я ищу что-то более простое, чем использование события рисования, и это с меньшей вероятностью вызовет проблемы в других реализациях.
- Одна основная причина, по которой я хочу избежать чего-либо, связанного с событием Paint, заключается в том, что у вас для "резервного копирования" текста в другую переменную, чтобы вы могли очистите
.Text
, чтобы он не отображался на кнопке в дополнение к вашей пользовательской визуализации, но после визуализации вы не можете переназначить .Text
в событии Paint, потому что это снова вызывает событие, вызывая бесконечное l oop , что означает, что с этого момента вы должны оставить .Text
кнопки пустым.
ЗДЕСЬ КОД:
(с излишними комментариями в Paint, чтобы объяснить причину того, как я с этим справляюсь)
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
btn.ForeColor = Color.MidnightBlue
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.DarkGray
Else
btn.ForeColor = Color.MidnightBlue
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 is what caused an infinite loop necessitating the use of the .Tag property.
End Sub
End Module
ЗАКЛЮЧИТЕЛЬНОЕ ПРИМЕЧАНИЕ:
Я открыт для любых советов по оптимизации code Я должен решить свои проблемы, но я совершенно убежден, что единственный способ решить определенные проблемы - это сделать тот же трюк, не касаясь Paint.