Подтвердить что ты не робот

Как показать сообщение "Загрузка... подождите" в Winforms для длинной формы загрузки?

У меня есть форма, которая очень медленная, потому что в форме есть много элементов управления.

В результате форма занимает много времени для загрузки.

Как мне сначала загрузить форму, затем отобразить ее и во время загрузки указать другую форму, которая имеет сообщение типа "Загрузка... подождите.?"

4b9b3361

Ответ 1

Использование отдельного потока для отображения простого, пожалуйста, подождите, когда сообщение переполняется, особенно если у вас нет большого опыта в потоковой передаче.

Более простой подход - создать форму "Подождите" и отобразить ее как окно без режима непосредственно перед формой медленной загрузки. После того, как основная форма закончит загрузку, скройте форму ожидания.

Таким образом, вы используете только один основной поток пользовательского интерфейса, чтобы сначала отобразить форму ожидания, а затем загрузить основную форму.

Единственным ограничением для этого подхода является то, что ваша форма wait wait не может быть анимирована (например, анимированный GIF), потому что поток занят загрузкой основной формы.

PleaseWaitForm pleaseWait=new PleaseWaitForm ();

// Display form modelessly
pleaseWait.Show();

//  ALlow main UI thread to properly display please wait form.
Application.DoEvents();

// Show or load the main form.
mainForm.ShowDialog();

Ответ 2

Я смотрел на большинство размещенных решений, но натолкнулся на другой, который я предпочитаю. Он прост, не использует потоки и работает для того, что я хочу.

http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx

Я добавил к решению в статье и переместил код в базовый класс, из которого все мои формы наследуются. Теперь я просто вызываю одну функцию: ShowWaitForm() во время события frm_load() любой формы, для которой требуется диалоговое окно ожидания при загрузке формы. Здесь код:

public class MyFormBase : System.Windows.Forms.Form
{
    private MyWaitForm _waitForm;

    protected void ShowWaitForm(string message)
    {
        // don't display more than one wait form at a time
        if (_waitForm != null && !_waitForm.IsDisposed) 
        {
            return;
        }

        _waitForm = new MyWaitForm();
        _waitForm.SetMessage(message); // "Loading data. Please wait..."
        _waitForm.TopMost = true;
        _waitForm.StartPosition = FormStartPosition.CenterScreen;
        _waitForm.Show();
        _waitForm.Refresh();

        // force the wait window to display for at least 700ms so it doesn't just flash on the screen
        System.Threading.Thread.Sleep(700);         
        Application.Idle += OnLoaded;
    }

    private void OnLoaded(object sender, EventArgs e)
    {
        Application.Idle -= OnLoaded;
        _waitForm.Close();
    }
}

MyWaitForm - это имя формы, которую вы создаете, чтобы выглядеть как диалог ожидания. Я добавил функцию SetMessage(), чтобы настроить текст в форме ожидания.

Ответ 3

Вы хотите посмотреть экраны "Всплеск".

Покажите еще одну форму "Всплеск" и дождитесь завершения обработки.

Вот быстрый и грязный пост о том, как это сделать.

Вот лучший пример.

Ответ 4

Еще один способ сделать "Загрузка экрана" отображать только в определенное время, поставить его перед событием и уволить его после того, как событие закончило выполнение задания.

Например: вы хотите отобразить форму загрузки для события сохранения результата в виде файла MS Excel и уволить его после завершения обработки, выполните следующие действия:

LoadingWindow loadingWindow = new LoadingWindow();

try
{
    loadingWindow.Show();                
    this.exportToExcelfile();
    loadingWindow.Close();
}
catch (Exception ex)
{
    MessageBox.Show("Exception EXPORT: " + ex.Message);
}

Или вы можете поместить loadingWindow.Close() внутри блока finally.

Ответ 5

Простое решение:

using (Form2 f2 = new Form2())
{
    f2.Show();
    f2.Update();

    System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here

А затем замените свою нагрузку на сон.
Это блокирует поток пользовательского интерфейса, специально.

Ответ 6

Вы должны создать фоновый поток для создания и заполнения формы. Это позволит вашему потоку переднего плана показывать загружаемое сообщение.

Ответ 8

Лучший подход, когда у вас также есть анимированное изображение, - это:

1- Вам нужно создать "WaitForm", который получит метод, который будет выполняться в фоновом режиме. Как этот

public partial class WaitForm : Form
{
    private readonly MethodInvoker method;

    public WaitForm(MethodInvoker action)
    {
        InitializeComponent();
        method = action;
    }

    private void WaitForm_Load(object sender, EventArgs e)
    {
        new Thread(() =>
        {
            method.Invoke();
            InvokeAction(this, Dispose);
        }).Start();
    }

    public static void InvokeAction(Control control, MethodInvoker action)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action();
        }
    }
}

2 - Вы можете использовать Waitform, подобный этому

private void btnShowWait_Click(object sender, EventArgs e)
{
    new WaitForm(() => /*Simulate long task*/ Thread.Sleep(2000)).ShowDialog();
}

Ответ 9

Я положил некоторый анимированный gif в форме под названием FormWait, а затем я назвал его как:

// show the form
new Thread(() => new FormWait().ShowDialog()).Start();

// do the heavy stuff here

// get the form reference back and close it
FormWait f = new FormWait();
f = (FormWait)Application.OpenForms["FormWait"];
f.Close();

Ответ 10

Ну, я делаю что-то вроде этого.

NormalWaitDialog/*your wait form*/ _frmWaitDialog = null;

//For static wait dialog
//On an Event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += async (s, e) =>
{
   Refresh();
   await Task.Run(() =>
   {
      //Do your stuff
   });
_frmWaitDialog.Close();
};
_frmWaitDialog.ShowDialog(this);



//For animated wait dialog
//On an event
_frmWaitDialog = new NormalWaitDialog();
_frmWaitDialog.Shown += (s, e) =>
{
   //create a async method and call the method here
   LoadDataAsync();
};
_frmWaitDialog.ShowDialog(this);

 //Async Method
 private async void LoadDataAsync(){
       await Task.Run(() =>
       {
          //Do your stuff
       });
       _frmWaitDialog.Close();
 }

Ответ 11

или если вам не нужно что-то необычное, например анимация и т.д., вы можете создать метку и закрепить ее для формирования, затем изменить ее z-index из окна контура документа на 0 и присвоить ему цвет фона, чтобы другие элементы управления не были видны, кроме запуска Application.DoEvents() один раз в событии загрузки формы и выполнить все кодирование в отображаемом событии формы, а в событии и в указанном событии установить для свойства видимого ярлыка значение false, а затем снова запустить Application.DoEvents().