Здравствуйте.
Есть задача реализовать фоновый текст в текстбоксе если ничего не введено в поле.
Сделал производный класс от TextBox
public partial class TextBoxExt : TextBox
{
public TextBoxExt() : base()
{
SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
base.OnPaintBackground(pevent);
if (Text == "")
{
pevent.Graphics.DrawString("Поиск ... ", new Font("Arial", Font.Size, FontStyle.Bold), Brushes.LightGray, new Point(0, 1));
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (Text == "")
{
e.Graphics.DrawString("Поиск ... ", new Font("Arial", Font.Size, FontStyle.Bold), Brushes.LightGray, new Point(0, 1));
}
}
}
Сам компонент помещен в другом UserControl.
И почему то возникают какие то странные глюки:
Первое это размер вводимого текста:
Сама фоновая строка печатается тем же размером что и Font контрола.
Он там где то 15 -16. Это видно по размеру текста:
Но когда я начинаю вводить текст то вводимый текст почему то вводится с размером родительского шрифта. это где то 8. Причем в фоне проглядывается моя строка.
И второй глюк:
Когда текстовое поле теряет фокус то текст обесцвечивается и мой и тот что ввели. Как будто просто сделали очистку. Но текст все равно там остается.
Че за фигня то ??
Пробовал всякие перерисовки делать, но никак не могу побороть эти два глюка.
Может кто подскажет что за бред?
Ну это ведь костыли … хотелось как то правильно сотворить.
Так а где его найти то?? Там внутри где то есть типа редактора чтото … у него своя политика отрисовки и позиционирования курсора. Если просто перерисовывать то дергается шрифт постоянно.
Да это смотря как посмотреть, события надежнее, точно будут работать всегда и везде. OnPaint это как раз скорее попытка нарисовать свой костыль поверх недокументированного непонятно чего. Даже если сработает, то не факт, что на всех системах, версиях .NET и т.д. Что и как рисуется зависит от стиля системы + еще в винформс большая часть стандартных контролов это обертки над WinApi контролами, так что надо разбираться как они работают, какие сообщения принимают и т.д. https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/TextBoxBase.cs
В общем я бы не лез в перерисовывание стандартных контролов винформс без необходимости, только если иначе совсем никак.
Вот в WPF и других современных аналогах этим можно заниматься, там дали нормальные возможности для этого.
Custom painting a TextBox most of the times impossible to do right. TextBox uses the Windows edit control which was never designed for this kind of thing. Your best bet is to NOT use Graphics.DrawString for text rendering but PInvoke TextOut Win32 function (or if you use .NET 2.0 you can try to use the TextRenderer class). Graphics.DrawString uses GDI+ instead of GDI which is used by the windows edit control and GDI+ uses a different font engine which is not always compatible with GDI in terms of text size, alignment etc. Of course you must ensure that you’re using exactly the some font to draw the text as TextBox does.
Even so you may run into problems because TextBox may not always call OnPaint but rather do some drawing in some other places like when handling keyboard or mouse messages.