tldr - сделал подкласс Textbox, текст выглядит странно, когда он имеет фокус. Какой правильный способ справиться с этим?
Для приложения моей компании VB.Net меня попросили заставить наши текстовые поля вести себя как текстовые поля Google, то есть они должны иметь рамку синего цвета вокруг них, когда они имеют фокус, и границу серого цвета, когда они делают не. Я уже могу сделать это, установив для BorderStyle текстового поля значение «Нет», а затем нарисовав соответствующий прямоугольник в событии Paint формы. Тем не менее, я должен сделать это для каждого текстового поля, которое я использую. И в нашем приложении их немало. Излишне говорить, что это боль, и я предпочел бы иметь один кусок кода, к которому я могу обратиться.
Итак, я решил, что у меня есть два варианта; Я могу либо создать пользовательский элемент управления, который содержит одно текстовое поле, которое использует вышеупомянутый метод, либо я могу написать свой собственный класс, который наследуется от класса TextBox и делает это поведение стандартным. Я решил использовать последний подход, и, переопределив метод OnPaint, я достиг желаемого поведения. Но теперь я сталкиваюсь с некоторыми новыми подводными камнями.
Основная проблема, с которой я сталкиваюсь, заключается в том, что текст в текстовом поле отображается неправильно, когда текстовое поле имеет фокус. Текст приобретает другой шрифт, выглядит жирным, а выделение выглядит шатким. Если текстовое поле теряет фокус, текст выглядит правильно. Я подозреваю, что мне нужно по-разному обрабатывать рисование для выделенного текста, но я не уверен, что мне нужно делать. Я обращаюсь с этим в методе OnPaint или мне нужно поймать это где-нибудь еще? Нужно ли вообще отказываться от этого подхода и просто создавать пользовательский элемент управления?
Бонусный вопрос: для любого, у кого есть опыт создания пользовательских текстовых полей, есть какие-нибудь советы или хитрости, о которых мне нужно знать? Я впервые делаю пользовательский элемент управления, поэтому я не знаю, чего ожидать.
edit: забыл упомянуть, что я могу переопределить OnPaint, потому что для флага UserPaint установлено значение true. Я предполагаю, что это было очевидно, но я просто хочу быть тщательным.
edit2: вот класс целиком.
Imports System.Drawing
Public Class MyCustomTextBox
Inherits TextBox
Public Sub New()
MyBase.New()
Me.BorderStyle = BorderStyle.None
SetStyle(ControlStyles.UserPaint, True)
End Sub
Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
'I want these textboxes to highlight all text by default
Me.SelectAll()
MyBase.OnGotFocus(e)
End Sub
Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
Me.SelectionLength = 0
MyBase.OnLostFocus(e)
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim p As Pen = Nothing
'MyBase.OnPaint(e)
e.Graphics.FillRectangle(Brushes.White, Me.ClientRectangle)
If Me.Focused Then
p = New Pen(Brushes.CornflowerBlue)
Else
p = New Pen(Brushes.Gainsboro)
End If
e.Graphics.DrawRectangle(p, 0, 0, Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)
e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), Me.ClientRectangle)
End Sub
End Class