Creating a dark background when a new form appears

2020-02-15 08:13发布

This is hard for me to actually explain so I created a mockup for what I want.

Mockuk example

Can someone here explain how I could make this? Maybe some code could help but I think a general idea or direction can be sufficient enough.

I want to darken the parent background whenever a new window is opened in front of it.

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-02-15 08:50

I don't know of any way to make Controls darken themselves. And since semi-transparent controls are a mess, too, here is a way that gets the effect by overlaying the Form by another, empty Form, which is semi-transparent:

Form fff;

fff = new Form();
fff.ControlBox = false;
fff.MinimizeBox = false;
fff.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
fff.Text = "";
fff.Size = Size;
fff.BackColor = Color.DarkSlateBlue;
fff.Opacity = 0.2f;
fff.Show();
fff.Location = this.Location;

If you want only the ClientRectangle to appear darkened change these lines:

fff.Size = ClientSize;
fff.Location = PointToScreen(Point.Empty);

After this you open the secondary Form and when you close it you hide this overlay Form again..

查看更多
男人必须洒脱
3楼-- · 2020-02-15 08:55

Take a screenshot of the form and paint a semi-transparent rectangle over it. Add that image to a panel the size of the form and bring it to the front. Display your dialog. Get rid of the panel:

    private void button1_Click(object sender, EventArgs e)
    {
        // take a screenshot of the form and darken it:
        Bitmap bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
        using (Graphics G = Graphics.FromImage(bmp))
        {
            G.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
            G.CopyFromScreen(this.PointToScreen(new Point(0, 0)), new Point(0, 0), this.ClientRectangle.Size);
            double percent = 0.60;
            Color darken = Color.FromArgb((int)(255 * percent), Color.Black);
            using (Brush brsh = new SolidBrush(darken))
            {
                G.FillRectangle(brsh, this.ClientRectangle);
            }
        }

        // put the darkened screenshot into a Panel and bring it to the front:
        using (Panel p = new Panel())
        {
            p.Location = new Point(0, 0);
            p.Size = this.ClientRectangle.Size;
            p.BackgroundImage = bmp;
            this.Controls.Add(p);
            p.BringToFront();

            // display your dialog somehow:
            Form frm = new Form();
            frm.StartPosition = FormStartPosition.CenterParent;
            frm.ShowDialog(this);
        } // panel will be disposed and the form will "lighten" again...
    }
查看更多
Anthone
4楼-- · 2020-02-15 08:57

Looks like you need to create an event (maybe include an enumerate for Start, Completed or make it a bool so it can signal Start/Completed in the same event). Have your large window subscribe to this event. When it is time to show/create the new form, fire the event (with the event arg set to Start). When the big window sees the "Start" event, it does whatever it needs and darkens itself. When the new form goes away, fire the Completed event. When the big form sees the "Completed" event, it restores itself.

查看更多
登录 后发表回答