質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.35%

C# 処理中にフォーム上に薄い膜を張りたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 9,004

score 10

C#でFORMアプリケーションでボタンを押下した際など何かの処理中に、フォームに薄いグレーの膜を張り、その薄い膜の中央で、くるくると回るインジケーターを表示しようとしてますが、フォーム全体を覆うような薄い膜を張る方法はないでしょうか。
Opacity を80% ほどに設定したFORMを表示すれば、見た目はそれっぽくなるのですが、ShowDialogでは後続の処理がとまり、Showでは、先頭のFORMを切り替える事ができるため、実現できませんでした。
また、ShowでTopMostをtrueにすることも試してみましたが、他のアプリケーションのウインドウにも掛かってしまい、うまくいきませんでした。
なにかよい方法なないでしょうか。

追記

    // 半透明にしたいコントロール
    public class CPanel : Panel
    {
        public CPanel()
        {
            //SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            //this.BackColor = Color.Transparent; // 透明
            this.BackColor = Color.FromArgb(80, 0, 0, 0); // 半透明
        }
    }

  // 半透明にしたいコントロールコントロールの配置
        private void Btn_Click(object sender, EventArgs e)
        {
            var f = new CPanel();
            f.Location = new Point(0, 0);
            this.Controls.Add(f);
            f.Parent = this;
            f.BringToFront();
        }

上記のコードを実行しても、半透明になっていないpanelがformに表示されるだけでした。
f.Parent = this;

f.Parent = Button01;
の様に、form上の別のコントロールを指定すると、そのコントロール(Button01)の上では半透明で表示されています。
希望としては、form全体に半透明で覆いたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2019/06/07 15:34

    フォームの子として半透明のユーザーコントロールを作り、それを前面に出す、と言って通じますか?

    キャンセル

  • Zenasp1401

    2019/06/07 16:01

    Zuishinさま、ご回答ありがとうございます。
    半透明のユーザーコントロールを作成し、表示することも考え試してみたのですが、うまくいきませんでした。
    試したのは、SupportsTransparentBackColorをtrueにした、panelやlabelをform上に配置してみましたが、思ったような結果になりませんでした。
    半透明のユーザーコントロールの作成方法が間違っているのでしょうか?

    キャンセル

  • Zuishin

    2019/06/07 16:26

    質問を編集してやってみたコードを追記し、期待とどこが違うのかを具体的に書いてください。コードはマークダウンのコードブロックを使ってください。

    キャンセル

  • Q71

    2019/06/07 17:00 編集

    ShowDialog ではなく、Show
    かつ、Owner指定

    キャンセル

回答 2

+1

簡単に考えていましたが、思ったより手ごわかったです。

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

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        class TranslucentPanel : Panel
        {
            public TranslucentPanel()
            {
                SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
            }

            protected override CreateParams CreateParams
            {
                get
                {
                    var result = base.CreateParams;
                    result.ExStyle |= 0x20;
                    return result;
                }
            }

            protected override void OnPaintBackground(PaintEventArgs e)
            {
                using (var brush = new SolidBrush(BackColor))
                {
                    e.Graphics.FillRectangle(brush, e.ClipRectangle);
                }
            }
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            var panel = new TranslucentPanel()
            {
                Parent = this,
                Dock = DockStyle.Fill,
                BackColor = Color.FromArgb(128, 128, 0, 0)
            };
            new Button()
            {
                Parent = panel,
                Location = new Point(15, 8),
                Text = "Close"
            }.Click += (s, a) =>
            {
                panel.Parent = null;
                panel = null;
            };
            panel.BringToFront();
            panel.Focus();
            panel.Invalidate();
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/10 10:09

    Zuishinさま、Q71さま

    お礼が遅くなり大変申し訳ございません。
    サンプルを作成していただき、ありがとうございます。
    お二方のお手を煩わせてしまいまして、大変申し訳ございません。
    お教えいただきましたサンプルの内容をしっかり勉強していくようにいたします。

    Q71さま
    大変申し訳ございません。
    先にご回答いただきました、Zuishinさまをベストアンサーとさせていただきます。

    お二方ともに、実際に動作するコードを作成していただいてありがとうございました。

    キャンセル

checkベストアンサー

0

もう一つ。フォームを上に貼り付ける方法。
NumericUpDown と、Button、Timer を1つずつ貼り付けています。
Form.Show メソッドを、IWindow32 引数付きで呼び出すと、そのウィンドウが親となり、必ず親より前に表示されます。
Form.Activated イベントで、Owner プロパティから親の表示位置、大きさを取得し、同じになるように設定します。
あとは、フォームリサイズを禁止しないといけないかな。
Form1.Shown イベントをハンドルしているのは、curtain を初めて表示したときに位置がとれなかったからです。その後、いろいろ変えたので、不要かもしれない。

namespace teratail_193679
{
    public partial class Form1 : Form
    {
        Form curtain;

        public Form1()
        {
            InitializeComponent();
            curtain = new Form();
            curtain.Size = this.Size;
            curtain.Opacity = 0.4;
            curtain.MaximizeBox = false;
            curtain.MinimizeBox = false;
            curtain.ControlBox = false;

            numericUpDown1.Value = 2;
            timer1.Tick += this.Timer1_Tick;
            this.Shown += this.Form1_Shown;
            this.FormClosed += this.Form1_FormClosed;
            curtain.Activated += this.Curtain_Activated;
        }

        private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
        {
            curtain.Dispose();
        }

        private void Curtain_Activated(Object sender, EventArgs e)
        {
            if (sender is Form me)
            {
                me.Location = me.Owner.Location;
                me.Opacity = 0.6;
                me.Size = me.Owner.Size;
            }
        }

        private void Form1_Shown(Object sender, EventArgs e)
        {
            this.Shown -= Form1_Shown;
            curtain.Hide();
        }

        private void Timer1_Tick(Object sender, EventArgs e)
        {
            curtain.Hide();
        }

        private void button1_Click(Object sender, EventArgs e)
        {
            timer1.Interval = (int)(numericUpDown1.Value * 1000);
            timer1.Start();
            curtain.Show(this);
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る