Dimming inactive forms

前端 未结 3 1381
囚心锁ツ
囚心锁ツ 2021-01-16 13:36

When opening Dialog form using Form.ShowDialog() I want to dim the rest of application with a shade of gray.

From my own research it seems that the way to do it is

相关标签:
3条回答
  • 2021-01-16 14:05

    I'm not sure what you mean by dimming the "rest of the application" but I will show you how to colour the application with a shade of gray with an opacity less than 100%.

    Code (I'm assuming you're using c#):

    Graphics g = this.CreateGraphics(); // Creating graphics for this form.
    g.FillRectangle(Color.FromArgb(80, 102, 90, 95), 0, 0, this.Width, this.Height); 
    // Draws a gray rectangle with an opacity of 30% over the whole form.
    

    Then to get rid of the gray rectangle you can use:

    this.Invalidate();
    

    Which will redraw the form, all the controls will stay the same but the gray will go away.

    Hope this Helps!

    0 讨论(0)
  • 2021-01-16 14:14

    An alternative to this approach is to use an inherited form instance which hides the showDialog. Then you can disable/enable all forms bar the current one. The code for the dummy form is to deal with the issue described here; Cannot fire form activate event - issue with disabled forms

    One of the advantages to this approach is that it requires no change to the normal handling of the showDialog method. Just call it like;

    if (dlg.ShowDialog(this) == DialogResult.OK) {
                // etc...
            }
    

    In your inherited form

    public abstract class MyBaseForm : XtraForm
    {
        private DialogResult setFormsToBackground(Form fParent)
        {
            Form dummyForm = new Form();
            dummyForm.ShowInTaskbar = false;
            dummyForm.FormBorderStyle = FormBorderStyle.None;
            dummyForm.Load += ((object sender, EventArgs e) => { (sender as Form).Size = new Size(0, 0); });
    
            List<Form> lstFormsToEnable = new List<Form>();
            for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
            {
                try
                {
                    Form checkfrm = Application.OpenForms[i];
                    if (checkfrm != this && dummyForm != this && checkfrm.Enabled)
                    {
                        lstFormsToEnable.Add(checkfrm);
                        checkfrm.Enabled = false;
                    }
                }
                catch (Exception ex)
                {
    
                }
            }
            dummyForm.Show();
            DialogResult result = DialogResult.None;
            if (fParent == null) result = base.ShowDialog();
            else result = base.ShowDialog(fParent);
            for (int i = lstFormsToEnable.Count - 1; i >= 0; i--)
            {
                try
                {
                    Form checkfrm = Application.OpenForms[i];
                    checkfrm.Enabled = true;
                }
                catch (Exception ex)
                {
    
                }
            }
            dummyForm.Close();
            return result;
        }
    }
    
    0 讨论(0)
  • 2021-01-16 14:27

    This is best done by overlaying the open forms with another form that's borderless and the same size. This allows you do make the entire form look disabled, including the controls and the title bar. Add a new class to your project and paste this code:

    using System;
    using System.Drawing;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    class DialogOverlay : IDisposable {
        public DialogOverlay() {
            var cnt = Application.OpenForms.Count;
            for (int ix = 0; ix < cnt; ++ix) {
                var form = Application.OpenForms[ix];
                var overlay = new Form { Location = form.Location, Size = form.Size, FormBorderStyle = FormBorderStyle.None,
                    ShowInTaskbar = false, StartPosition = FormStartPosition.Manual, AutoScaleMode = AutoScaleMode.None };
                overlay.Opacity = 0.3;
                overlay.BackColor = Color.Gray;
                overlay.Show(form);
                forms.Add(overlay);
            }
        }
        public void Dispose() {
            foreach (var form in forms) form.Close();
        }
        private List<Form> forms = new List<Form>();
    }
    

    And use it like this:

        private void DialogButton_Click(object sender, EventArgs e) {
            using (new DialogOverlay()) 
            using (var dlg = new Dialog()) {
                if (dlg.ShowDialog(this) == DialogResult.OK) {
                    // etc...
                }
            }
        }
    

    Tweak the Opacity and BackColor properties to adjust the effect. It will work with any kind of dialog, including the built-in ones like OpenFileDialog, and any set of open forms in your application. Beware that Application.OpenForms is a wee bit buggy.

    0 讨论(0)
提交回复
热议问题