Creating a dark background when a new form appears

2020-02-15 08:42发布

问题:

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

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.

回答1:

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...
    }


回答2:

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:

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.