简体   繁体   中英

Creating a Pop-Up form in C#

I am trying to create a windows form that gets displayed for 2 seconds when triggerd by an event, and then closes automatically.

I have tried several options. This is my current code:

        this.aletPopup.StartPosition = FormStartPosition.CenterScreen;
        this.aletPopup.Show();
        Thread.Sleep(2000);
        this.aletPopup.Close();

This preforms the actions that I desire, however, when the form loads it does not load the label or image which is on the form. Instead, the area where the image and label are become transparent. My desired output is this: 在此输入图像描述

I have also tried using this.aletPopup.ShowDialog(); , which does display the graphics. However, the form will not close automatically when using this method.

EDIT: I am attempting to use Michael Perrenoud's solution. However, I cannot get the form to close. I have a timer set at a 2000ms interval which is initally disabled. Am I overriding the OnShown correctly?

public AlertPopForm()
    {
        InitializeComponent();

    }

    private void closingTimer_Tick(object sender, EventArgs e)
    {
        closingTimer.Enabled = false;
        this.Close();
    }

    private void AlertPopForm_OnShown(object sender, System.EventArgs e)
    {
        closingTimer.Enabled = true;
        closingTimer.Start(); 
    }

Instead, how about leveraging ShowDialog , and then using a Timer on the dialog form. In the Tick event of the Timer , close the form.

this.aletPopup.StartPosition = FormStartPosition.CenterScreen;
this.aletPopup.ShowDialog();

You could even pass the interval into the .ctor of the dialog form if you wanted some flexibility.

It's very important to note here that you'd need to leverage the OnShown override to actually Start the Timer so the form is in fact shown to the user.

The reason can be in Message Loop. When you block your thread by Thread.Sleep, it also blocks Message loop.

You can make like this:

this.aletPopup.StartPosition = FormStartPosition.CenterScreen;
this.aletPopup.Show();
for(var i = 0; i<= 200; i++)
{
    Thread.Sleep(10);
    Application.DoEvents();
}
this.aletPopup.Close();

DoEvents will process messages from message queue during that time.

When calling Thread.Sleep you're blocking the UI thread, thus preventing it from processing UI events.

You need to ensure that Close is called after 2 seconds without actually blocking the main thread. There are a number of ways of doing this, such as using a Timer , or something like Task.Delay :

aletPopup.StartPosition = FormStartPosition.CenterScreen;
aletPopup.Show();
Task.Delay(TimeSpan.FromSeconds(2))
    .ContinueWith(t => aletPopup.Close(), 
    TaskScheduler.FromCurrentSynchronizationContext());

The reason this is happening, is that you are halting the thread that draws the form. So the form has time to display, but as it's being drawn, the thread is being stopped.

Easy enough to fix....

Add an event handler to the popup for the Load event with the following handler:

private async void handleLoad(Object sender, EventArgs args)
{
  await Task.Delay(2000);
  Close();
}

Remark Because you used Show() , the user could always click around this popup. If this is undesirable, then use ShowDialog() instead.

Did you try a refresh to redraw the form?

    this.aletPopup.StartPosition = FormStartPosition.CenterScreen;
    this.aletPopup.Show();

    this.alertPopup.Refresh();


    Thread.Sleep(2000);
    this.aletPopup.Close();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM