19

一部の領域で透明にする必要があるコントロール (System.Windows.Forms.Control から派生) があります。SetStyle() を使用してこれを実装しました。

public TransparentControl()
{
    SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    this.BackColor = Color.Transparent.
}

これで、フォームと透明なコントロールの間にコントロールがない場合に機能します。ただし、透明なコントロールの下に別のコントロールがある場合 (ここでの使用例)、それは機能しません。中間コントロールは描画ではありませんが、下のフォームは透けて見えます。CreateParams をオーバーライドし、次のように WS_EX_TRANSPARENT フラグを設定することで、必要な効果を得ることができます。

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT
        return cp;
    }
}

ここでの問題は、コントロールの描画が本当に遅くなることです。コントロールは既にダブル バッファリングされているため、何もする必要はありません。パフォーマンスへの影響が非常に大きく、受け入れられません。他の誰かがこの問題に遭遇しましたか? 私が見つけることができるすべてのリソースは、方法 1 を使用することを提案していますが、これも私の場合は機能しません。

編集:回避策があることに注意してください。子 (透明) コントロールは、単に親の Graphics オブジェクトに自分自身を描画することができますが、それは本当に見苦しく、解決策がまったく好きではありません (私が持っているすべてかもしれませんが)。

EDIT2: .NET で透明性がどのように機能するかについてのアドバイスに従って、透明なコントロールを含むユーザー コントロールに IContainer インターフェイスを実装しました。ISite を実装するクラスを作成しました。自分の子コントロールを UserControl の Components コレクションに追加しました。Container プロパティはデバッガーで正しく並んでいますが、まだ透過効果が得られません。誰にもアイデアはありますか?

4

7 に答える 7

9

これは私が作った単純なものです..私が見つけた唯一の問題は、交差するコントロールが更新されたときに更新されないことです..

現在のコントロールの背後にある/交差するコントロールをビットマップに描画し、そのビットマップを現在のコントロールに描画することで機能します。

protected override void OnPaint(PaintEventArgs e)
{
    if (Parent != null)
    {
        Bitmap behind = new Bitmap(Parent.Width, Parent.Height);
        foreach (Control c in Parent.Controls)
            if (c.Bounds.IntersectsWith(this.Bounds) & c != this)
                c.DrawToBitmap(behind, c.Bounds);
        e.Graphics.DrawImage(behind, -Left, -Top);
        behind.Dispose();
    }
}
于 2012-05-19T07:55:48.740 に答える
5

以下の変更により、処理が少し速くなることがわかりました。

if((this.BackColor == Color.Transparent) && (Parent != null)) {
    Bitmap behind = new Bitmap(Parent.Width, Parent.Height);
    foreach(Control c in Parent.Controls) {
        if(c != this && c.Bounds.IntersectsWith(this.Bounds)) {
            c.DrawToBitmap(behind, c.Bounds);
        }
    }
    e.Graphics.DrawImage(behind, -Left, -Top);
    behind.Dispose();
}

this.Widthまた、 /this.Heightの代わりにParent.Width/を使用するとさらに高速になると思いますがParent.Height、いじる時間がありませんでした。

于 2012-09-11T19:51:06.463 に答える
3

子コントロールの下の親を手動でペイントすることにしました。 ここに良い記事があります。

于 2009-02-27T02:05:48.480 に答える
-2

これはトリックを行います、少なくとも私にはあります:

protected override void OnPaintBackground(PaintEventArgs e)
{
    //base.OnPaintBackground(e);
    this.CreateGraphics().DrawRectangle(new Pen(Color.Transparent, 1), new Rectangle(0, 0, this.Size.Width, this.Size.Height));
}
于 2013-08-08T23:47:51.050 に答える