为什么在面板上绘制的文本会消失?

5

我正在尝试在面板上绘制文本(面板具有背景图片)。

它运行得很好,但是当我最小化再最大化应用程序时,文本就消失了。

我的代码:

using (Graphics gfx = Panel1.CreateGraphics())
{
    gfx.DrawString("a", new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
}

如何使它保持静态,以免丢失?
4个回答

9

继承自Panel,添加一个属性来表示您需要写入的文本,并重写OnPaint方法():

public class MyPanel : Panel
{
    public string TextToRender
    {
        get;
        set;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.DrawString(this.TextToRender, new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
    }
}

这样,每个面板都将知道它需要渲染的内容,并且将知道如何绘制自己。


只有一个问题,我应该调用“TextToRender =“myText””还是它会自动获取? - Ivan Prodanov
1
John:你需要设置 myPanel1.TextToRender = "a"; myPanel2.TextToRender = "b"; 除此之外,它们会“自动工作”。 - Reed Copsey
第9行出现错误:“没有找到适合覆盖方法的方法” - 覆盖方法。 - Ivan Prodanov
你可能忘记从面板继承。 - Ed S.

4

只需添加一个Paint事件的处理程序:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawString("a", new Font("Tahoma", 5), Brushes.White, new PointF(1, 1));
}

好的,我没有说完。我有62个面板,每个面板上都要写不同的整数,是否有其他替代方案或者你有什么建议? - Ivan Prodanov
@John:我建议创建一个继承自Panel的控件,并为文本创建一个属性。在您的控件中覆盖OnPaint方法以编写字符串(使用相同的代码)。 - Jon B
是的,但这意味着要手动处理60个OnPaint事件。 :( - Ivan Prodanov
1
@John:我认为你误解了。你需要创建一个从Panel派生的新控件,并实现它的绘画,然后提供一个属性以指定它应该绘制的数量。接着,在需要的地方使用这个新控件替换原本的Panel并提供相应的属性值即可。 - Jeff Yates

2
如果您不使用Paint事件,则只是在控件所在的屏幕上绘制。控件不知道这一点,因此它不知道您打算让文本留在那里...
如果您将要绘制在面板上的值放在其Tag属性中,则可以为所有面板使用相同的绘画事件处理程序。
此外,您需要正确处理Font对象的释放,否则您将拥有很多等待完成的对象,然后将它们的资源返回给系统。
private void panel1_Paint(object sender, PaintEventArgs e) {
   Control c = sender as Control;
   using (Font f = new Font("Tahoma", 5)) {
      e.Graphics.DrawString(c.Tag.ToString(), f, Brushes.White, new PointF(1, 1));
   }
}

0

当你绘制某些东西时,它只会保留到下一次窗体刷新。

当窗体刷新时,将调用Paint事件。因此,如果您想确保文本不会消失,您需要在Paint事件中包含绘制它的代码。

您可以使用Control.Invalidate触发重绘,但否则无法预测何时会发生。


新的问题是我不需要写“a”,而是一个特定的整数,而且面板不是一个,paintEvent是唯一实现这个目标的方法吗? - Ivan Prodanov
将其作为类的属性,并在OnPaint中简单地绘制该属性的值。 - Ed S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接