Я пытаюсь нарисовать TextBox на расширенной стеклянной рамке моей формы. Я не буду описывать эту технику, это хорошо известно. Вот пример для тех, кто этого не слышал: http://www.danielmoth.com/Blog/Vista-Glass-In-C.aspxРисование TextBox в расширенной стеклянной рамке без WPF
Дело в том, что сложнее нарисовать эту стеклянную рамку. Поскольку черный считается 0-альфа-цветом, все черное исчезает.
Есть, по-видимому, способы противодействия этой проблеме: эта формальность не влияет на рисование сложных форм GDI +. Например, этот код может быть использован, чтобы сделать метку на стекло (примечание: GraphicsPath
используется вместо DrawString
для того, чтобы обойти ужасную проблему ClearType):
public class GlassLabel : Control
{
public GlassLabel()
{
this.BackColor = Color.Black;
}
protected override void OnPaint(PaintEventArgs e)
{
GraphicsPath font = new GraphicsPath();
font.AddString(
this.Text,
this.Font.FontFamily,
(int)this.Font.Style,
this.Font.Size,
Point.Empty,
StringFormat.GenericDefault);
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.FillPath(new SolidBrush(this.ForeColor), font);
}
}
Аналогичным образом, такой подход может быть использован для создать контейнер на площади стекла. Обратите внимание на использование полигонов вместо прямоугольника - при использовании прямоугольника его черные части рассматриваются как альфа.
public class GlassPanel : Panel
{
public GlassPanel()
{
this.BackColor = Color.Black;
}
protected override void OnPaint(PaintEventArgs e)
{
Point[] area = new Point[]
{
new Point(0, 1),
new Point(1, 0),
new Point(this.Width - 2, 0),
new Point(this.Width - 1, 1),
new Point(this.Width -1, this.Height - 2),
new Point(this.Width -2, this.Height-1),
new Point(1, this.Height -1),
new Point(0, this.Height - 2)
};
Point[] inArea = new Point[]
{
new Point(1, 1),
new Point(this.Width - 1, 1),
new Point(this.Width - 1, this.Height - 1),
new Point(this.Width - 1, this.Height - 1),
new Point(1, this.Height - 1)
};
e.Graphics.FillPolygon(new SolidBrush(Color.FromArgb(240, 240, 240)), inArea);
e.Graphics.DrawPolygon(new Pen(Color.FromArgb(55, 0, 0, 0)), area);
base.OnPaint(e);
}
}
Теперь моя проблема: как я могу нарисовать TextBox? После большого количества Googling, я пришел со следующими растворами:
- подклассов
OnPaint
метод текстового поля в. Это возможно, хотя я не мог заставить его работать правильно. Это должно включать в себя рисование некоторых магических вещей, которые я не знаю, как это сделать. - Изготовление на заказ
TextBox
, возможно, наTextBoxBase
. Если у кого есть good, действительные и рабочие примеры, и думает, что это может быть хорошим общим решением, пожалуйста, скажите мне. - Использование
BufferedPaintSetAlpha
. (http://msdn.microsoft.com/en-us/library/ms649805.aspx). Недостатком этого метода может быть то, что углы текстового поля могут выглядеть странно, но я могу жить с этим. Если кто-то знает, как правильно реализовать этот метод из объекта Graphics, скажите мне. Я лично этого не делаю, но пока это лучшее решение. Честно говоря, я нашел отличную статью на C++, но я слишком ленив, чтобы ее преобразовать. http://weblogs.asp.net/kennykerr/archive/2007/01/23/controls-and-the-desktop-window-manager.aspx
Примечание: Если я когда-нибудь удастся с методами BufferedPaint, я клянусь с/о том, что я буду делать простую DLL с все общие элементы управления Windows Forms рисуем на стекле.
Ответил себя в другом потоке: http://stackoverflow.com/questions/7061531/rendering-controls-on-glass-solution-found-needs-double-buffering-perfecting – Lazlo