2015-02-04 2 views
0

У меня есть форма с анимацией, которую я показываю при выполнении некоторых запросов для других форм. Я делал некоторые исследования, как показать эту анимированную форму по запросам и придумать как это сделать:Тема для анимированной «загрузки» формы

public partial class ProcessingForm : Form 
{ 
    private static Thread processingFormThread; 

    public ProcessingForm() 
    { 
     InitializeComponent(); 
    } 

    public void StartThreadOnProcessingForm() 
    { 
     processingFormThread = new Thread(() => { new ProcessingForm().ShowDialog(); }); 
     processingFormThread.Start(); 
    } 

    public void CloseThreadOnProcessingForm() 
    { 
     processingFormThread.Abort(); 
    } 
} 

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

public void Foo() 
{ 
    ProcessingForm pf = new ProcessingForm(); 
    pf.StartThreadOnProcessingForm(); 
    // some request/data actions 
    Form requestForm; 
    if (requestdata!= null) 
    { 
     requestForm = new requestForm(data); 
     pf.CloseThreadOnProcessingForm(); 
     requestForm.Show(); 
     requestForm.SetDataForForm(requestdata); 
    } 
} 

Это швами как довольно простое решение, но я не видел ничего подобного во время исследования, поэтому мне кажется, что я делаю что-то неправильно. Мой вопрос - есть ли лучший способ сделать такую ​​простую вещь?

+0

Что вы хотите, не очень-то понимаете? – ZoomVirus

+2

'processingFormThread.Abort();' Нет. Просто нет. –

+0

Я не уверен, что решение для потоковой обработки, которое я здесь делал, было правильным, потому что люди предлагали использовать backgroundworker для отображения анимированных форм, в то время как некоторые действия выполнялись. Также я не уверен, что Abort является правильным способом отменить поток для этой формы. – Buggy

ответ

1

Один из способов приблизиться к этому - передать Action в вашу форму выполнения и выполнить это действие в отдельном потоке из формы выполнения. Когда действие закончится, вы закроете форму выполнения.

Например, вы могли бы сделать что-то подобное в вашей форме прогресс:

public partial class ProgressForm: Form 
{ 
    public ProgressForm(Action action) 
    { 
     _action = action; 
     InitializeComponent(); 
    } 

    protected override void OnShown(EventArgs e) 
    { 
     base.OnShown(e); 

     Task.Factory.StartNew(() => 
     { 
      _action(); 
      _finished = true; 
      BeginInvoke(new Action(Close)); 
     }); 
    } 

    protected override void OnClosing(CancelEventArgs e) 
    { 
     // Prevent the user from closing the form until the action has completed. 

     if (!_finished) 
      e.Cancel = true; 
    } 

    private readonly Action _action; 
    private volatile bool _finished; 
} 

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

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

    private void button1_Click(object sender, EventArgs e) 
    { 
     using (var progress = new ProgressForm(action)) 
     { 
      progress.ShowDialog(); 
     } 
    } 

    static void action() 
    { 
     Thread.Sleep(10000); 
    } 
} 
0

честно говоря, я не очень понимаю, что вы пытаются добиться, но есть две очевидные проблемы:

  1. Запуск новой темы для вызова ShowDialog не имеет смысла. Точка использования ShowDialog вместо Show - это создать диалоговое окно modal, которое блокирует выполнение (текущего потока) до тех пор, пока диалог не будет закрыт. Выполнение этого в новом потоке поражает всю цель.

  2. Как отмечено Мэтью Уотсоном, Abort является плохим. См: What's wrong with using Thread.Abort()

Я предлагаю вызов ProcessingForm немодальных (Show), сделать его Topmost и отключить другие формы (без нитей). Затем выполните действия с данными в фоновом режиме Task (async/await). Когда задача будет завершена, вы закроете ProcessingForm и снова включите другую форму.

0

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

Простым решением является опрос статического свойства с именем «Занят» и вызов «Показать по форме», если true, и скрыть, если false. Вы можете избежать опроса, поместив логику в настройщик свойств «Занят».

Из основного приложения вы только что установили Popup.Busy = true перед длительной работой и ложными, когда закончите.

Просто запустите всплывающее окно в новой теме.

Смежные вопросы