下面的控件在矩形中绘制一个字符串。在鼠标移动时,对字符串矩形进行了命中测试,并通过CreateGraphics重新绘制字符串。令人恼火的问题是文本的绘制方式与Paint处理程序中的相同;它似乎被大约1个像素所取代,效果就像一个粗体字体。如何创建与Paint处理程序中的图形对象完全相同的图形对象,以便以相同的方式绘制文本?通常,您会在Paint事件中使所有内容无效并重绘,但我可能有数百个其他绘图项,并且只想绘制字符串。我是否应该尝试在Paint事件之外进行任何绘图,或者这是一个错误?
示例控件:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test.TestModes
{
public partial class ExampleControl: UserControl
{
private const string testString = "0123456789";
private RectangleF stringRect = new RectangleF(10, 10, 100, 20);
public ExampleControl()
{
InitializeComponent();
}
private void ExampleControl_Paint(object sender, PaintEventArgs e)
{
Font font = new Font("Arial", 12, FontStyle.Regular);
e.Graphics.DrawString(testString, font, Brushes.Black, stringRect);
font.Dispose();
}
private void DrawString(bool hit)
{
Font font = new Font("Arial", 12, FontStyle.Regular);
using(Graphics g = CreateGraphics())
{
g.SetClip(ClientRectangle);
if(hit)
g.DrawString(testString, font, Brushes.Red, stringRect);
else
g.DrawString(testString, font, Brushes.Black, stringRect);
}
font.Dispose();
}
private void ExampleControl_MouseMove(object sender, MouseEventArgs e)
{
if(stringRect.Contains(e.Location))
DrawString(true);
else
DrawString(false);
}
private void button1_Click(object sender, EventArgs e)
{
Invalidate();
}
}
}
答案 0 :(得分:8)
CreateGraphics()调用间接地让你陷入困境。问题是文本的抗锯齿。正常的绘画循环在绘制顶部之前擦除背景。在您的情况下,您的绘图文本不会发生在现有文本之上。副作用是每次绘制时用于创建锯齿的像素变得更暗。最终的结果是大胆的外观和明显的锯齿状文字轮廓。
修复很容易:在绘制之前先用干净的石板开始:
using (Graphics g = CreateGraphics()) {
g.Clear(this.BackColor); <=== added
g.SetClip(ClientRectangle);
// etc..
}
你现在也会在绘图中遇到一个被称为“闪烁”的问题。它可能还不是那么明显,但是当你做更多的绘画时它会。通过双缓冲抑制闪烁。 Windows窗体支持的功能,但仅限于使用标准绘图技术。换句话说:没有CreateGraphics()。