C# windows.forms.panel两次调用绘制

C# windows.forms.panel两次调用绘制,c#,winforms,panel,onpaint,C#,Winforms,Panel,Onpaint,我有一个面板,里面有多个面板。我已将主面板中的OnPaint改写为以下内容: protected override void OnPaint(PaintEventArgs e) { Graphics graph = e.Graphics; graph.Clear(Color.Black); InvokePaintBackground(this, e); graph.ScaleTransform(scale, sca

我有一个面板,里面有多个面板。我已将主面板中的OnPaint改写为以下内容:

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics graph = e.Graphics;
        graph.Clear(Color.Black);
        InvokePaintBackground(this, e);

        graph.ScaleTransform(scale, scale);

        foreach (childPanel child in childPanels)
        {
            child.onPaint(this, e);
        }

        graph.ResetTransform();
    }
我遇到的问题是,第一个控件(spot 0中的控件)的onPaint函数被调用了两次,因此我得到了两个版本的子面板,一个具有缩放功能,另一个不具有缩放功能。第二个onPaint似乎由子控件本身调用


如何防止它这样做?

这是因为所有
控件
对象都会自己绘制,并且该方法由Windows自动调用。解决方案是根本不依赖这种功能-去掉面板,或者将
Visible
设置为
false

您究竟为什么要在子控件上调用OnPaint?Windows将自行管理绘制调用。您不应该直接调用它们,尤其是对于从单独的绘制调用中收到的图形上下文


如果需要请求绘制子控件,请改用该方法。它将一个区域(或整个控件)标记为无效,以便Windows对其进行绘制。这样做的好处是Windows足够聪明,可以知道如果在同一个绘制周期内多次使其无效,它将不会多次重新绘制。

这是固有的行为。您只需使用
私有boolsecondcall对变量进行排序,并仅在第二次调用时进行缩放。

我想要明确控制调用顺序(出于分层目的,尽管我认为控件列表中的顺序可以解决这一问题),并且能够设置一次图形缩放,而不是对每个子级进行缩放。这不起作用,我希望孩子们的面板是透明的(这样他们就可以在彼此的上面画画),这种方法破坏了这一点。我建议你放弃这种方式,试着重新思考整个交易。我猜ScaleTransform不应该用于儿童控件绘制。有了GDI,在遵循文档的时候很难做到正确,但是冒险进行黑客攻击确实是自找麻烦。