C # WaitCursor при загрузке формы - PullRequest
4 голосов
/ 01 декабря 2009

У меня есть форма, для отображения которой требуется несколько секунд. Эта форма вызывается через:

using (ResultsForm frm = new ResultsForm())
{
    this.Visible = false;
    frm.ShowDialog();
    this.Visible = true;
}

Полезно, чтобы я установил курсор по умолчанию на Cursors.WaitCursor, ожидая, когда форма наконец-то отобразится. В настоящее время я могу только успешно выполнить это, используя статическое свойство Current:

using (ResultsForm frm = new ResultsForm())
{
    //this.Visible = false;
    Cursor.Current = Cursors.WaitCursor;
    frm.ShowDialog();
    //this.Visible = true;
}

Но у этого есть две проблемы:

  • Это вынуждает меня отключить функцию скрытия MainForm, которую я хотел бы сохранить.
  • Увеличивает связь, так как Cursor.Current = Cursor.Default; должен вызываться в событии ResultsForm Shown.

Как я могу изменить Курсор, пока форма загружается, не изменяя первый фрагмент кода и избегая соединения?

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

Ответы [ 5 ]

2 голосов
/ 01 декабря 2009

Это заставляет меня отключить функцию скрытия MainForm, которую я хотел бы сохранить.

Вы должны быть в состоянии сделать оба без проблем.

Увеличивает связь, так как Cursor.Current = Cursor.Default; должен вызываться в событии ResultsForm Shown

Вы пытались полностью поместить логику курсора в код диалога ResultsForm? Вы должны иметь возможность установить Cursor.Current = Cursors.WaitCursor; внутри конструктора ResultsForm , а затем установить Cursor.Current = Cursor.Default; внутри события Shown.

Это сохранит логику полностью в диалоге и вне основного окна. Вы также можете оставить переключение видимости в главном окне.

1 голос
/ 01 декабря 2009

Курсор изменится на WaitCursor, но он будет существовать только долю секунды. Проблема в том, что при скрытии вашей главной формы курсор перекрывает окно, которое находится за вашей основной формой. Или рабочий стол. Открытое окно получает сообщение WM_SETCURSOR из Windows, и оно меняет курсор на предпочитаемую форму.

Но есть большая проблема с вашим подходом. После закрытия диалогового окна появляется доля секунды, когда окно в вашем приложении не видно. Windows вынуждена найти другое окно, на которое нужно сфокусироваться, оно не будет окном в вашем приложении. Когда ваша основная форма снова становится видимой, она может оказаться за окном, которое получило фокус. Такое поведение, как правило, немного ненадежно, возможно, вы еще его не нашли.

Вы можете решить обе проблемы, скрыв окно другим способом:

  this.Opacity = 0.01;
1 голос
/ 01 декабря 2009

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

Однако, если вам нужен только курсор в этом конкретном случае отображения формы, вы можете использовать лямбду (или анонимный делегат, если вы имеете дело с C # 2.0) для обработчика событий:

using (ResultsForm frm = new ResultsForm())
{
    this.Visible = false;

    var oldCursor = Cursor.Current;
    Action<object, EventArgs> restoreCursor = 
        delegate
        {
            Cursor.Current = oldCursor;
            frm.Shown -= restoreCursor;
        };
    frm.Shown += restoreCursor;

    Cursor.Current  = Cursor.WaitCursor
    frm.ShowDialog();
}
1 голос
/ 01 декабря 2009

Почему вы должны удалить this.Visible = false? Вы все еще должны быть в состоянии сделать это при установке курсора.

Было бы приемлемым решением, чтобы ResultsForm установил курсор вместо родительской формы? Получите его, чтобы установить курсор, прежде чем он начнет код, который занимает все время, а затем установите его обратно в конце.

0 голосов
/ 01 декабря 2009

Вы можете сделать основную форму владельцем второй формы и сделать ее модальной:

frm.ShowDialog(this);

Затем в frm добавьте "Cursor.Current = Cursors.WaitCursor;" в конструкторе и добавьте "Cursor.Current = Cursor.Default;" в событии Показано .

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

Form1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WaitCursorTwoForms
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();
      }

      private void ButtonClick(object sender, EventArgs e)
      {
         using(Form2 form2 = new Form2())
         {
            form2.ShowDialog(this);
         }
      }
   }
}

Form2:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WaitCursorTwoForms
{
   public partial class Form2 : Form
   {
      public Form2()
      {
         Cursor.Current = Cursors.WaitCursor;
         InitializeComponent();
         for (int i = 0; i < 10; i++)
         {
            Thread.Sleep(1000);
         }
      }

      private void OnShown(object sender, EventArgs e)
      {         
         Cursor.Current = Cursors.Default;
      }
   }
}
...