しばらくこれを調べて、おそらく 20 の異なる実装を読みましたが、真に透過的なコントロールを実装するための、しっかりした、コントロールベース、フレームワークベースの一般的なソリューションをまだ見ていません。
このおそらく単純化されたアプローチはまったく何もせず、決して使用されないルーチン (InvalidateEx) を作成します: http://bytes.com/topic/c-sharp/answers/248836-need-make-user-control-transparent
これは、以前の回答が得ていたものを示唆しているようです: https://web.archive.org/web/20141227200000/http://bobpowell.net/transcontrols.aspx
ただし、タイマーティックを使用して InvalidateEx メソッドを実行します。
これは、ラベル オブジェクトが独自の透明度を実装しているように見える方法を詳しく説明しながら、多層コントロールを放棄し、すべての描画を単一のレイヤー パネルで処理しているように見えます: http://www.codeproject.com/Articles/25048/How- to-Use-Transparent-Images-and-Labels-in-Window
これは完全に非フレームワーク ベースの方法です: http://www.codeproject.com/Articles/30135/General-solution-for-transparent-controls
この回答で受け入れられた解決策は、単に私にはうまくいきません:透明なコントロールの透明なコントロール?
私が取得するコントロールは、透明な画像が描かれた一般的な単色 (白) です。
だから、私は自分の実装を開始します。
ボトムアップの GDI 描画に依存したくない、つまり、すべての描画を最も親のフォームで実行したい、透明なビットマップへの事前レンダリングを行いたくない、Forms.Control 以外のものから継承したくないこれは、透明性を短縮するために独自の巧妙なトリックを実行しています。完全な透過性をサポートするコントロール サーフェスに描画する方法の真相を知りたいと思っています。たとえば、ラベル コントロールの内部には完全な実装が含まれているようですが、どのように機能するのでしょうか?
論理的には、透明なコントロールは単純な 1 ビット クリップ領域に依存することはできず、ほぼ完全な状態を維持する必要があります。コントロールの多層化は正しく処理する必要があります。つまり、無限ループを引き起こさずに正しい描画順序などです。
最初の最も一般的な推奨事項は次のとおりです。
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Transparent
私が理解している最初の行は、と同義です
Protected Overrides ReadOnly Property CreateParams As System.Windows.Forms.CreateParams
Get
Dim result As System.Windows.Forms.CreateParams = MyBase.CreateParams
result.ExStyle = result.ExStyle Or WindowsMessages.WS_EX_TRANSPARENT
Return result
End Get
End Property
継承されるクラスに応じて、動作が大きく異なります。Forms.Control の場合、OnPaintBackground は、親コントロールの背景色でクリップの四角形をクリアすることを選択します。賢すぎない。
ベースの OnPaintBackground 呼び出しをオーバーライドして削除すると、コントロールはその下にあるものを上書きせずに「ダーティ」のままになります。透明色を使用して消去すると (楽観的なアプローチ)、黒の透明ピクセルのフィールドが生成され、コントロールが完全に黒く表示されます。
論理的には、これは理にかなっています。効率を高めるための基礎となるコントロールは、このコントロールが予想される領域をドローオーバーで再描画しません。フォームのその領域は更新されることはなく、フォームが存在する前の状態が維持されます。これへの透明色の描画は少し混乱します。これは、グラフィックス バッファーには下にあるピクセルさえ含まれておらず、コントロールを黒く見せるために黒の透明なものに置き換えられた実際の何も含まれていないことを意味するためです。
最初の課題は、コントロール自体が再描画されたときの処理であり、その領域ですべての基になるコントロールを再描画し (コントロール自体を自動的に無効にしてスタック オーバーフローを開始することなく)、基になる最新のピクセルを自分自身でペイントします。 . 私はまだこれを行う方法を見つけていません。最も近いのは、.net コードを掘り下げて、ButtonRenderer.DrawParentBackground メソッドを見つけることです。これは大部分は機能しているように見えますが、簡単なテストでは、重なり合うコンポーネントの z オーダーがまだ正しく処理されておらず、基になるコントロールがこのコントロールの上に描画されていることが示されました。
2 番目の課題は、基になるコントロールが変更されたときに、コントロールが適切に再描画されるようにすることです。課題 1 で自動無効化を切り離すことにより、コントロールにそれ自体を無効にするように通知し、その親を無効にしないようにすることが難しくなります。
誰かがこの問題を完全に解決した場合は、コードを提供してください。そうでない場合は、問題の 1 つまたは複数の部分をどのように処理するかについての経験を提供してください。
どうもありがとう。
編集:
WS_EX_TRANSPARENT に従って WS_EX_TRANSPARENT に関する想定された詳細が表示されます- 実際には何をしますか?
調査の更新: ButtonRenderer.DrawParentBackground は、Application.EnableVisualStyles() が使用され、単に親の背景描画を強制する場合にのみ、実際には Control 自体によって使用されます。の同義語のようです
InvokePaintBackground(Parent, e.Graphics)
親コントロールのすべての背景描画の詳細を再現します。