コントロールにドロップシャドウを追加する方法はありますか?
この機能を備えたコントロールはありますか?
CreateParams
次のようにプロパティを上書きする必要があります。
private const int CS_DROPSHADOW = 0x00020000;
protected override CreateParams CreateParams
{
get
{
// add the drop shadow flag for automatically drawing
// a drop shadow around the form
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
この質問は6年前からあり、答えが必要です。これを行う必要がある人は誰でも、私のソリューションから任意のコントロールセットの答えを推定できることを願っています。私はパネルを持っていて、すべての子コントロールの下にドロップシャドウを描きたいと思っていました-この場合は1つ以上のパネルです(ただし、このソリューションは、コードを少し変更するだけで、他のコントロールタイプにも適しています)。
コントロールのドロップシャドウは、そのコントロールのコンテナーの表面に描画する必要があるため、コンテナーのPaint()イベントに関数を追加することから始めます。
Container.Paint += dropShadow;
dropShadow()は次のようになります。
private void dropShadow(object sender, PaintEventArgs e)
{
Panel panel = (Panel)sender;
Color[] shadow = new Color[3];
shadow[0] = Color.FromArgb(181, 181, 181);
shadow[1] = Color.FromArgb(195, 195, 195);
shadow[2] = Color.FromArgb(211, 211, 211);
Pen pen = new Pen(shadow[0]);
using (pen)
{
foreach (Panel p in panel.Controls.OfType<Panel>())
{
Point pt = p.Location;
pt.Y += p.Height;
for (var sp = 0; sp < 3; sp++)
{
pen.Color = shadow[sp];
e.Graphics.DrawLine(pen, pt.X, pt.Y, pt.X + p.Width - 1, pt.Y);
pt.Y++;
}
}
}
}
明らかに、コンテナのコレクションから別のコントロールタイプを選択でき、いくつかの小さな調整で影の色と深さを変えることができます。
一番上の答えは実際には影を生成しますが、私はいくつかの理由で個人的にそれに満足していませんでした:
それで、これらすべてのことのために、私は自分のプロジェクトのために自分自身を書くことになり、ここでそれを共有したいと思いました:
public partial class Form1 : Form
{
List<Control> shadowControls = new List<Control>();
Bitmap shadowBmp = null;
public Form1()
{
InitializeComponent();
shadowControls.Add(panel1);
this.Refresh();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (shadowBmp == null || shadowBmp.Size != this.Size)
{
shadowBmp?.Dispose();
shadowBmp = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb);
}
foreach (Control control in shadowControls)
{
using (GraphicsPath gp = new GraphicsPath())
{
gp.AddRectangle(new Rectangle(control.Location.X, control.Location.Y, control.Size.Width, control.Size.Height));
DrawShadowSmooth(gp, 100, 60, shadowBmp);
}
e.Graphics.DrawImage(shadowBmp, new Point(0, 0));
}
}
private static void DrawShadowSmooth(GraphicsPath gp, int intensity, int radius, Bitmap dest)
{
using (Graphics g = Graphics.FromImage(dest))
{
g.Clear(Color.Transparent);
g.CompositingMode = CompositingMode.SourceCopy;
double alpha = 0;
double astep = 0;
double astepstep = (double)intensity / radius / (radius / 2D);
for (int thickness = radius; thickness > 0; thickness--)
{
using (Pen p = new Pen(Color.FromArgb((int)alpha, 0, 0, 0), thickness))
{
p.LineJoin = LineJoin.Round;
g.DrawPath(p, gp);
}
alpha += astep;
astep += astepstep;
}
}
}
}
この実装では、に追加されたすべてのコントロールshadowControls
が滑らかな影でペイントされます。シャドウを生成する主な関数は。を使用するため、非長方形の形状に対してこれを実装できるはずですGraphicsPath
。フォームに描画する前に、シャドウを別のビットマップに描画することが重要であることに注意してください。これは、メイン関数が機能するための合成モードを必要とするためSourceCopy
です。つまり、最初に別のサーフェスに描画しない場合、シャドウの背後にあるものは完全になります。置き換えられ、透明度の側面は役に立たない。私は10歳の質問に答えようとしていますが、うまくいけば、これは誰かを助けるでしょう!
WPFには、代わりにそれを使用するように拡張できる場合がありますが、GDI +の機能が制限されているため、Windowsフォームに代替手段があるとは思いません。
これは物議を醸す意見です、あなたはコードなしでそれをします。メインパネルの境界線スタイルを固定シングルに設定します。その下に3つのパネルを作成し、各パネルをすべての方向に1ピクセル大きくします。3つのパネルはそれぞれ明るい灰色の色合いです。完璧ではありませんが、安くて簡単です。