c#

【.net】[c#]Windowsフォームでオーバーレイメッセージを表示する

今日はc# Windowsフォームでオーバーレイを表示する方法。

よくWebで見る警告や確認のメッセージが最前面にくるやつです。

WPFだと簡単に実装できるのですが、Windowsフォームだと少し面倒です。
実装のイメージとしては、現在表示中のフォームの上に透過したフォームを被せるイメージです。

何が面倒かというと、FormのOpacityプロパティを透過に設定したフォームを被せると、
他のコントロールまで透過されてしまいます。

こんな感じで

オーバーレイ失敗

ちょっと見るに堪えないですね。

ではちょっと小細工してみます。

オーバーレイ成功

どうでしょう?見るに堪えるレベルになりました。

小細工の内容はこうです。

まず透過率(Opacity)と背景色(BackColor)のみ設定したフォームを被せます。
次にコントロールを配置し、透明キー(TransparencyKey)を設定したフォームを被せます。

2個のフォームを重ねるわけですね。こんな順で。

オーバーレイフォーム順


サンプルソース

まず1つ目のフォーム(OverlayBase.cs)


using System;
using System.Windows.Forms;

namespace OverlaySample
{
    /// <summary>
    /// <para>透過率のみ設定するForm</para>
    /// <para>※コントロールを配置するとコントロールまで透過されるため、コントロールを配置するFormは上に被せる</para>
    /// </summary>
    internal partial class OverlayBase : Form
    {
        public OverlayBase()
        {
            InitializeComponent();
        }

        public OverlayBase(Form owner) : this()
        {
            // 表示位置は親フォームにあわせる
            this.StartPosition = FormStartPosition.CenterParent;
            // Formの枠なし
            this.FormBorderStyle = FormBorderStyle.None;
            // 透過率60%
            this.Opacity = 0.6;
            // 親フォームの情報を引き継ぐ
            this.Location = owner.Location;
            this.Size = owner.Size;
            this.Font = owner.Font;
        }

        /// <summary>
        /// Shownで2つ目のフォームを呼んでまう
        /// </summary>
        /// <param name="buttons"></param>
        private void OverlayBase_Shown(object sender, EventArgs e)
        {
            OverlayParts parts = new OverlayParts(this);
            this.DialogResult = parts.ShowDialog();
            this.Close();
        }
    }
}

そして2つ目のフォーム(OverlayParts.cs)


using System.Drawing;
using System.Windows.Forms;

namespace OverlaySample
{
    /// <summary>
    /// 背景のみ透過させ、部品を配置するForm
    /// </summary>
    internal partial class OverlayParts : Form
    {
        public OverlayParts()
        {
            InitializeComponent();
        }

        public OverlayParts(Form owner) : this()
        {
            // 表示位置は親フォームにあわせる
            this.StartPosition = FormStartPosition.CenterParent;
            // Formの枠なし
            this.FormBorderStyle = FormBorderStyle.None;
            // 背景色を透明化するキーに指定
            this.TransparencyKey = this.BackColor;
            
            // ラベルの書式設定
            lblMessage.Anchor = AnchorStyles.None;
            lblMessage.Text = "実行します。\r\nよろしいですか?";
            lblMessage.Font = new Font(owner.Font.FontFamily, 14f);
            lblMessage.ForeColor = Color.White;
            // ラベルを中央に配置する
            lblMessage.Left = (this.Width / 2) - (lblMessage.Width / 2); 

            // ボタンの配置
            LocateButton();

            // 親フォームの情報を引き継ぐ
            this.Location = owner.Location;
            this.Size = owner.Size;
            this.Font = owner.Font;
        }

        /// <summary>
        /// ボタンの配置
        /// </summary>
        /// <param name="buttons"<</param>
        private void LocateButton()
        {
            Button btn = new Button();
            btn.Anchor = AnchorStyles.None;
            btn.Location = new Point(130, 186);
            btn.Size = new Size(80, 32);
            btn.TabIndex = 51;
            btn.Text = "OK";
            btn.UseVisualStyleBackColor = true;
            btn.Click += (sender, e) =< { this.DialogResult = DialogResult.OK; this.Close(); };
            this.Controls.Add(btn);

            btn = new Button();
            btn.Anchor = AnchorStyles.None;
            btn.Location = new Point(230, 186);
            btn.Size = new Size(80, 32);
            btn.TabIndex = 52;
            btn.Text = "キャンセル";
            btn.UseVisualStyleBackColor = true;
            btn.Click += (sender, e) =< { this.DialogResult = DialogResult.Cancel; this.Close(); };
            this.Controls.Add(btn);
        }
        
    }
}

あとは実際に使用する画面で下記のように書けばOKです。


    OverlayBase overlay = new OverlayBase(this);
    overlay.ShowDialog();

このコードはイケてるか?と聞かれればイケてはないですね。
イケてない点ついでに言うと、テーマを
「Windows 7 ベーシック」
にしていると、Windowの左上と右上が丸まってると思うのですが、よく見るとそれをカバーできていません。

丸みカバーできず

Windows 8や10だと大丈夫かもしれません。角ばっているので。

おしまい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です