c#中的重载控件绘图存在文本呈现问题
我对一个控件(ToolStripStatusLabel)进行了子分类,以尝试覆盖它的绘制方式。目前,我希望这段代码实际上什么也不做,但它会导致一个奇怪的输出:c#中的重载控件绘图存在文本呈现问题,c#,winforms,rendering,alphablending,C#,Winforms,Rendering,Alphablending,我对一个控件(ToolStripStatusLabel)进行了子分类,以尝试覆盖它的绘制方式。目前,我希望这段代码实际上什么也不做,但它会导致一个奇怪的输出: protected override void OnPaint(PaintEventArgs e) { // Create a temp image to draw to and then put that onto the control transparently using (Bitmap bmp = new Bitmap(
protected override void OnPaint(PaintEventArgs e)
{
// Create a temp image to draw to and then put that onto the control transparently
using (Bitmap bmp = new Bitmap(this.Width, this.Height))
{
using (Graphics newGraphics = Graphics.FromImage(bmp))
{
// Paint the control to the temp graphics
PaintEventArgs newEvent = new PaintEventArgs(newGraphics, e.ClipRectangle);
base.OnPaint(newEvent);
// Copy the temp image to the control
e.Graphics.Clear(this.BackColor);
e.Graphics.DrawImage(bmp, new Rectangle(0, 0, this.Width, this.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel);//, imgAttr);
}
}
}
当我运行此代码时,控件上的文本非常奇怪,预期的图像在顶部,实际输出在底部:
看起来控件在绘制文本时,alpha与抗锯齿文本的混合出错
我尝试过的事情:
- 设置
和e.graphics
newGraphics
- 设置
textrendinghint
- 将
的像素格式设置为32Bpp ARGB和预乘ARGBnewGraphics
- 在请求基类渲染之前,请使用控件背景色清除
newGraphics
- TL;DR:您需要使用重新实现
OnRenderItemText
,可能使用graphics.DrawString()来最终绘制文本的
另一种选择是使用a(如@Reza Aghaei所述)。然后可以将UseCompatibleTextRendering
设置为true,使其使用GDI+而不是GDI
这似乎是文本在最低层次上呈现的固有问题。如果添加一个普通ToolStripStatusLabel并将其TextDirection设置为Vertical90,则会得到相同的结果,其中文本的抗锯齿看起来与背景没有alpha 查看,您将看到调用了一个非常类似的代码位,其中文本被渲染为位图,然后在本例中旋转:
using (Bitmap textBmp = new Bitmap(textSize.Width, textSize.Height,PixelFormat.Format32bppPArgb)) {
using (Graphics textGraphics = Graphics.FromImage(textBmp)) {
// now draw the text..
textGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
TextRenderer.DrawText(textGraphics, text, textFont, new Rectangle(Point.Empty, textSize), textColor, textFormat);
textBmp.RotateFlip((e.TextDirection == ToolStripTextDirection.Vertical90) ? RotateFlipType.Rotate90FlipNone : RotateFlipType.Rotate270FlipNone);
g.DrawImage(textBmp, textRect);
}
}
因此,当文本呈现到位图图形上下文(与控件的图形上下文相反)时,这似乎是一个基本问题。最终的结果是:
我认为这是进入GDI(与GDI+相反)的过程,而GDI+已经
最好的方法是编写一个重新实现
OnRenderItemText
,可能是从源代码中获得了一些“灵感”.尝试PixelFormat.Format32bppPArgb
以获得位图
,或者在绘制之前清除位图而不是控件。如果我没有弄错的话,这是一种需要预乘alpha的问题。我忘了提到我已经尝试显式设置像素格式-我尝试了32bppARGB,但将其更改为32bppPARGB没有任何效果。我还尝试在将控件转到renderSorry之前清除newGraphics上下文,基类只是一个ToolStripStatusLabel@joey关于背景清理:当使用DrawString()时,这当然有帮助(我刚刚用它做了一个测试),但奇怪的是,它对基类绘图的结果没有影响。我想知道微软在那里做什么!如果您试图自定义ToolStripStatusLabel
的外观,则创建渲染器是一种方法。举个例子来看。
using( WindowsGraphicsWrapper wgr = new WindowsGraphicsWrapper( dc, flags ))
{
using (WindowsFont wf = WindowsGraphicsCacheManager.GetWindowsFont( font, fontQuality )) {
wgr.WindowsGraphics.DrawText( text, wf, bounds, foreColor, GetIntTextFormatFlags( flags ) );
}
}