Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

c# - How to display a "loading" overlay on windows forms while the form is loading its controls (or updating them)?

I'm looking for an effective way to notify the user that a given form is currently loading (or updating) it's UI and it will take few seconds.

This may occurs at initial load or at update. Since it's very intensive and modifying ui controls, this has to be done on the ui thread, and therefore blocking the user.

Changing the cursor is not enought, I want to get a similar effect than on ajax pages, with the whole area that is overlayed by a semi transparent panel with an animated gear on the center.

Have you done something like that already? Or do you know interesting websites I should consult?

Thanks a lot

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Take a look at this post with a great answer that mimics the Ajax style on WinForms

Javascript Like Modal Window for WinForms.
Javascript Like Modal Window for WinForms

Here is a custom Form that'll do what you want... alter to your taste:

public partial class ModalLoadingUI : Form
{
    #region Constants
    private readonly Color BackgroundFadeColor = Color.FromArgb(50, Color.Black);
    #endregion

    #region Constructors
    public ModalLoadingUI()
    {
        InitializeComponent();
    }
    #endregion

    #region Properties
    /// <summary>
    /// Gets or Sets the main form that will be used as a background canvas for the loading form.
    /// </summary>
    public Form BackgroundForm { get; set; }

    /// <summary>
    /// Gets or Sets the text to displayed as the progress text.
    /// </summary>
    public string Title
    { 
        get
        {
            return label1.Text;
        }

        set
        {
            label1.Text = value;
        }
    }

    /// <summary>
    /// Gets or Sets the value of the progress bar.
    /// </summary>
    public int? Progress
    {
        get
        {
            if (progressBar1.Style == ProgressBarStyle.Marquee)
            {
                return null;
            }
            else
            {
                return progressBar1.Value;
            }
        }

        set
        {
            if (value == null)
            {
                progressBar1.Style = ProgressBarStyle.Marquee;
                progressBar1.Value = 100;

                label2.Visible = false;
            }
            else
            {
                progressBar1.Style = ProgressBarStyle.Continuous;
                progressBar1.Value = value.Value;

                label2.Text = string.Format("{0}%", value);
                label2.Visible = true;
            }
        }
    }

    /// <summary>
    /// Gets or Sets a value to indicate if the background form should be faded out.
    /// </summary>
    public bool UseFadedBackground { get; set; }

    /// <summary>
    /// Gets or Sets a value to indicate if the splash box is to be displayed.
    /// </summary>
    public bool UseSplashBox
    {
        get
        {
            return picShadow.Visible;
        }

        set
        {
            if (value == true)
            {
                picShadow.Visible = true;
                panel1.Visible = true;
            }
            else
            {
                picShadow.Visible = false;
                panel1.Visible = false;
            }
        }
    }
    #endregion

    #region Base Events
    private void ModalLoadingUI_Load(object sender, EventArgs e)
    {
        if (this.BackgroundForm != null)
        {
            this.Location = this.BackgroundForm.Location;
        }
    }

    private void ModalLoadingUI_VisibleChanged(object sender, EventArgs e)
    {
        if (this.Visible == true)
        {
            if (this.BackgroundForm != null)
            {
                this.Location = this.BackgroundForm.Location;
            }
        }

        if (System.Diagnostics.Debugger.IsAttached == true)
        {
            this.TopMost = false;
        }
        else
        {
            this.TopMost = true;
        }
    }

    private void ModalLoadingUI_Shown(object sender, EventArgs e)
    {
    }
    #endregion

    #region Public Methods
    /// <summary>
    /// Paints the background form as the background of this form, if one is defined.
    /// </summary>
    public void CaptureBackgroundForm()
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new MethodInvoker(CaptureBackgroundForm));
            return;
        }

        if (this.BackgroundForm == null)
        {
            return;
        }


        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
        Graphics g = Graphics.FromImage(bmpScreenshot);

        try
        {
            // COPY BACKGROUND
            int x = this.BackgroundForm.Left;
            int y = this.BackgroundForm.Top;
            var size = this.BackgroundForm.Size;

            g.CopyFromScreen(x, y, 0, 0, size, CopyPixelOperation.SourceCopy);

            // FADE IF DESIRED
            if (this.UseFadedBackground == true)
            {
                var rect = new Rectangle(0, 0, size.Width, size.Height);

                g.FillRectangle(new SolidBrush(BackgroundFadeColor), rect);
            }

            // PAINT SPLASH BOX SHADOW IF DESIRED
            if(this.UseSplashBox == true)
            {
                PaintPanelShadow(g);
            }
        }
        catch (Exception e)
        {
            g.Clear(Color.White);
        }

        this.BackgroundImage = bmpScreenshot;
    }

    /// <summary>
    /// Paints a shadow around the panel, if one is defined.
    /// </summary>
    /// <param name="g">The graphics object to paint into</param>
    private void PaintPanelShadow(Graphics g)
    {
        var shadowImage = picShadow.Image;

        var x = panel1.Left + (panel1.Width / 2) - (shadowImage.Width / 2);
        var y = panel1.Top + (panel1.Height / 2) - (shadowImage.Height / 2);

        g.DrawImage(shadowImage, x, y, shadowImage.Width, shadowImage.Height);
    }
    #endregion
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...