在C#中绘制父级和父级子级的自定义背景 [英] Painting custom background of parent and parent children in C#

查看:105
本文介绍了在C#中绘制父级和父级子级的自定义背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用本教程,以便我可以有一个透明的按钮.它在主要背景下工作正常,但不会覆盖其他子项.如果我使用BringToFront(),则该位置没有其他孩子的绘画.

I am trying to use this tutorial so that I can have a transparent button. It works fine for the main background, but it doesn't draw over the other children. If I use BringToFront() it then doesn't have the other child's drawing where it should be.

我已经开始通过将其添加到代码中来解决它:

I have started to get around it by adding this to the code:

foreach (Control child in Parent.Controls) {
    if(child != this) {
        InvokePaintBackground(child, pea);
        InvokePaint(child, pea);
    }
}

尽管我得到了一些想要的东西,但它位于错误的位置(在左侧,而不是在应该放置的中间),并且在孩子的绘画事件中绘制了形状也没有出现.

And although I get some of what I want, it's in the wrong location (on the left instead of in the middle where it shoudl be) and the shapes which are drawn in the child's paint event also aren't showing up.

我该如何进行修改,以便让我的所有其他孩子也能完全理解透明性?

How can I modify so that I will have all of the other children as well giving the full illusion of transparency?

注意::我不担心除其他孩子外的任何人痛苦,因为我知道没有孩子,还有很多其他地方可以找到如何做的事情.递归地获取所有孩子.

Note: I'm not worried about paining for anybody but other children, as I know that there aren't any, and there are pleny of other places to find out how to get all of the children recursively.

感谢 C.Evenhuis 答案,现在可以使用了.我的实现很简单(只有另一个孩子),所以这是我的代码.对于将来的读者,请务必阅读该文章,以获得fll范围.

Thanks to C.Evenhuis answer, its now working. My implementation is simple (only one other child), so this is my code. For future readers, be sure to read that post though to get a fll scope.

using (PaintEventArgs pea = new PaintEventArgs(e.Graphics, rect)) {
    pea.Graphics.SetClip(rect);
    InvokePaintBackground(Parent, pea);
    InvokePaint(Parent, pea);
    foreach (Control child in Parent.Controls) {
        if (child != this) {
            pea.Graphics.ResetTransform();
            pea.Graphics.TranslateTransform(child.Left - Left, child.Top - Top);
            InvokePaintBackground(child, pea);
            InvokePaint(child, pea);
        }
    }
}

推荐答案

绘画时,所有控件均假定其左上角位于(0,0)坐标处.这是通过在调用OnPaint之前将Graphics对象的视口设置为控件的坐标来实现的.

When painting, all controls assume their top-left corner is at the (0, 0) coordinate. This is achieved by setting the viewport of the Graphics object to the coordinates of the control before OnPaint is called.

要绘制其他控件,您必须手动执行以下操作:

To paint the other controls, you'll have to do this manually:

if (child != this) 
{
    int offsetX = control.Left - Left;
    int offsetY = control.Top - Top;

    // Set the viewport to that of the control
    pevent.Graphics.TranslateTransform(offsetX, offsetY);

    // Translate the clip rectangle to the new coordinate base
    Rectangle clip = pevent.ClipRectangle;
    clip.Offset(-offsetX, -offsetY); // Ugly self-modifying struct
    PaintEventArgs clippedArgs = new PaintEventArgs(pevent.Graphics, clip);
    InvokePaintBackground(control, clippedArgs);
    InvokePaint(control, clippedArgs);
    pevent.Graphics.TranslateTransform(-offsetX, -offsetY)
}

如果基础控件是包含自己的子控件的Panel,则情况会变得更加复杂-这些控件不会与父控件一起自动绘制.如果您也需要支持,我建议将WM_PRINT消息发送到父控件和当前控件下方的缓冲控件-对于兄弟控件,您可以设置PRF_CHILDREN标志以使其也绘制其后代.

Things get a bit more complicated if the underlying control is a Panel containing child controls of its own - these are not automatically painted along with their parent. If you need to support that too I suggest sending a WM_PRINT message to the parent control and to the silbing controls below the current control - for the sibling controls you can then set the PRF_CHILDREN flag to let it paint its descendants too.

目前,您还正在绘制 all 个同级控件-包括当前控件上方的同级控件.您可能希望让循环倒退,并在到达当前控件时按break键.不过,直到您开始堆叠多个透明控件时,这才不是真正的问题.

Also currently you're painting all sibling controls - including the ones above the current control. You might want to let the loop go backwards and break when you reach the current control. This won't be a real issue though until you start stacking multiple transparent controls.

这篇关于在C#中绘制父级和父级子级的自定义背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆