0

我有一个具有透明背景的面板。当我将其中一些添加到控件时,具有最高索引的子元素会呈现在顶部。有人可以告诉我发生了什么以及如何解决这个问题吗?

这是面板的代码:

public ref class TransparentPanel : public Panel
{
public:
    Bitmap^ _image;

    TransparentPanel(Bitmap^ image){_image = image;Width = image->Width;Height = image->Height;}

    virtual property System::Windows::Forms::CreateParams^ CreateParams{
        System::Windows::Forms::CreateParams^ get(void) override {
            System::Windows::Forms::CreateParams^ cp = Panel::CreateParams;
            cp->ExStyle |= 0x00000020;//WS_EX_TRANSPARENT
            return cp;
        }
    }

    virtual void OnPaintBackground(PaintEventArgs^ e) override {}
    virtual void OnPaint(PaintEventArgs^ e) override {e->Graphics->DrawImage(_image, Rectangle(0, 0, Width, Height));}
};
4

2 回答 2

0

不确定您期望什么,但通常的做法是在之前的控件之上绘制最后插入的控件。

如果您有精确的排序,您可以使用 z-indexing 以便您的面板正确定位。

否则你不能简单地以相反的顺序插入它们;)应该可以解决问题。

于 2013-06-07T17:21:42.877 回答
0

我知道这个问题已经有一年多了,但我已经为类似的问题苦苦挣扎了几天。因为我现在找到了一个似乎可行的解决方案,所以我想我会在这里为未来的患者(包括我自己!)发帖。

似乎为一系列相互重叠的自定义绘制控件设置WS_EX_TRANSPARENT样式 (0x20) 会产生奇怪的效果,即它们的绘制顺序与它们的 z 顺序相反,即 z-index 的控件0 将首先被绘制(为了测试这一点,在您覆盖的 OnPaint 方法中将每个控件的 z-index 写入控制台)。

到目前为止似乎对我有用的解决方案是扩展父控件(在我的情况下是 DevExpress PanelControl,尽管我也尝试过使用标准的 .Net 面板)并在那里启用WS_EX_COMPOSITED扩展窗口样式:

protected override CreateParams CreateParams {
    get {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;   //WS_EX_COMPOSITED

        return cp;
    }
}

这种样式设置只是颠倒了子控件的绘制顺序(所以它变成了从下到上),从而解决了问题:)

有关扩展窗口样式的更多信息,请参见此处:http: //msdn.microsoft.com/en-us/library/windows/desktop/ff700543 (v=vs.85).aspx 。
此页面警告说在 Windows 8 中使用它会闪烁,但我已经在 Windows 8.1 中尝试过并且没有发现任何问题,所以它可能已经修复。

我只能假设 .NET 控件以某种方式呈现不同(可能使用剪辑区域等),这就是为什么它们不会表现出相同的行为,但是按从上到下的顺序绘制控件对我来说似乎是一个错误,因为我可以不要想到你会想要这样做的情况!

于 2014-09-25T11:50:33.180 回答