私は最近Visual Studioを探索し始めました。スライドメニューを作ってみました。より具体的には、ユーザーがボタンを押すと、サブメニューが右側にポップアップします。それを達成するために、自分自身のサイズを変更するためにPanel
を配置しました。機能性とは別に、もう少しデザインを追加して、Panel
を少し色あせて見せたかったです。
Visual StudioのPanels
には不透明度がないことを知っていますが、それを実現する方法についてのトリックのアイデアを誰かが知っているかどうか考えていました。 Picture Box
しかし、それもプロパティとして不透明度を持っていませんでした。さらにデザインを追加したかったので、ビジュアルスタジオが提供する通常のMenu
objectの使用を避けました。何か案は?
Panel
から継承するクラスを作成します。ControlStyle.Opaque
SetStyle
を使用したコンストラクタでの制御用。Trueの場合、コントロールは不透明に描画され、背景は描画されません。
CreateParams
を上書きして設定 WS_EX_TRANSPARENT
スタイル。このスタイルで作成されたウィンドウを透明にすることを指定します。つまり、ウィンドウの下にあるウィンドウは、ウィンドウによって隠されません。このスタイルで作成されたウィンドウは、その下にあるすべての兄弟ウィンドウが更新された後にのみ、WM_Paintメッセージを受け取ります。
Opacity
プロパティを作成します。OnPaint
をオーバーライドし、Brush
とBackGroundColor
から作成されるアルファ対応Opacity
を使用して背景を塗りつぶします。完全なコード
public class ExtendedPanel : Panel
{
private const int WS_EX_TRANSPARENT = 0x20;
public ExtendedPanel()
{
SetStyle(ControlStyles.Opaque, true);
}
private int opacity = 50;
[DefaultValue(50)]
public int Opacity
{
get
{
return this.opacity;
}
set
{
if (value < 0 || value > 100)
throw new ArgumentException("value must be between 0 and 100");
this.opacity = value;
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 255 / 100, this.BackColor)))
{
e.Graphics.FillRectangle(brush, this.ClientRectangle);
}
base.OnPaint(e);
}
}
スクリーンショット
コントロールを「透明」にするには、親の適切な領域をコントロールにペイントする必要があります。これは、Button
がコンテンツを描画する前に行うことで、角の丸い部分が透明になります。
半透明を模倣するには、フォームをパネルにペイントしてから、アルファで何かを描画します。
private void panel1_Paint(object sender, PaintEventArgs e)
{
PaintTransparentBackground(panel1, e);
using (Brush b = new SolidBrush(Color.FromArgb(128, panel1.BackColor)))
{
e.Graphics.FillRectangle(b, e.ClipRectangle);
}
}
private static void PaintTransparentBackground(Control c, PaintEventArgs e)
{
if (c.Parent == null || !Application.RenderWithVisualStyles)
return;
ButtonRenderer.DrawParentBackground(e.Graphics, c.ClientRectangle, c);
}
ButtonRenderer.DrawParentBackground
は、パネルと重なるフォームのコントロールをペイントせず、フォームの背景のみをペイントします。