スタッキングコントロール(Winforms C#)(透明)
-
22-07-2019 - |
質問
オブジェクトをコンテナ内にスタックできるGUIを作成するように求められました。ユーザーは、ボックスをトップダウンビューポイントから表示します。また、内部に何が積み上げられているかを確認したいと考えています。これを解決するために私が最初に考えたのは透明性でした。透明性に関するいくつかの投稿を読みましたが、両方の画像が透明であるという問題を解決するものを見つけられなかったため、両方がスタックされているかどうかを確認できました。
コントロールを他のコントロールの上に透明にするにはどうすればよいですか。これが本当に不可能な場合;この問題に対するより良いアプローチは何ですか?
この問題を解決するためにカスタムコントロール(パブリック部分クラスMyControl:Control)を使用しています。最終的にコントロール上の画像が透明になりました。親フォームに描かれたものはすべて画像を通して表示されます(親にonPaintを使用して楕円と正方形をペイントしています)が、その上に配置された他のコントロールは透明ではなくなりました。
これを達成するために使用しているコードは以下のとおりです。
public Image Image
{
get { return m_Image; }
set { m_Image = value; }
}
private void GridControl_Paint(object sender, PaintEventArgs e)
{
if (Image != null)
{
Graphics g = e.Graphics;
Bitmap bitMap = new Bitmap(Image);
//This is not working... the color array always comes back empty
//This is how I would rather making things transparent...
Color[] colorArray = bitMap.Palette.Entries;
if (colorArray.Length > 0)
{
ColorMap[] colorMap = new ColorMap[colorArray.Length];
for (int index = 0; index < colorArray.Length; index++)
{
colorMap[index] = new ColorMap();
colorMap[index].OldColor = colorArray[index];
colorMap[index].NewColor = Color.Transparent;
}
}
//Ok fine so the above is not working... let me force it.
//Get each pixel in the image and change the color.
else
{
for (int x = 0; x < bitMap.Width; x++)
{
for (int y = 0; y < bitMap.Height; y++)
{
Color pixelColor = bitMap.GetPixel(x, y);
Color newColor = Color.FromArgb(100, pixelColor);
bitMap.SetPixel(x, y, newColor);
}
}
}
bitMap.MakeTransparent();
g.DrawImage(bitMap, this.ClientRectangle);
}
}
解決 2
この問題の良い解決策を見つけることができませんでした。これを実現する唯一の方法は、カスタムコントロールを作成し、多くのカスタムコードを使用することです(まだ完全には機能していません)。私は答えでこのスレッドを閉じます:
このフォーラムで答えるのは複雑すぎます。
他のヒント
WinFormsの使用にロックされていますか?あなたが説明するようなかなりややトリッキーなグラフィックスを行う必要があり、それを回避するためにアプリを再設計できない場合、WPFに飛躍することができます。
GDI +グラフィックスでプレイしてからしばらく経ったので、ここにアイデアがあります(ただしコードはありません;)):
スタックされたコントロールは実際に機能する必要がありますか?そうでない場合は、外観をビットマップにコピーして非表示にし、独自のペイントルーチンでビットマップを使用できます。コントロールを機能させる必要がある場合は、非表示を解除できます。
ところで、bitmap.GetPixelまたはSetPixelの使用は非常に遅いです。 32ビットのビットマップ(青、緑、赤、アルファはバイト)を操作する古いコードをいくつか紹介します:
BitmapData bmpData = bitmap.LockBits(pixelRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
unsafe
{
byte* bytes = (byte*)bmpData.Scan0;
for (int row = 0; row < pixelRect.Height; row++)
{
for (int col = 0; col < pixelRect.Width * 4; ) // * 4: 4 bytes per pixel
{
bytes[row * bmpData.Stride + col++] = blue;
bytes[row * bmpData.Stride + col++] = green;
bytes[row * bmpData.Stride + col++] = red;
bytes[row * bmpData.Stride + col++] = alpha;
}
}
}
// Unlock the bits.
bitmap.UnlockBits(bmpData);