В настоящее время я работаю над своей персональной реализацией диалога ожидания, которая поддерживает обновление хода выполнения задачи и отмену задачи. Банкомат это что-то вроде:
public partial class WaitDialog : Form
{
WaitDialog()
{
InitializeComponent();
}
public static WaitDialog Instance
{
get { return WaitDialogCreator.uniqueInstance; }
}
public DialogResult ShowDialog(Form owner, string message)
{
Instance.lblWaitMessage.Text = message;
return Instance.ShowDialog(owner);
}
public DialogResult ShowDialog(Form owner, BackgroundWorker worker)
{
...
}
public DialogResult ShowDialog(Form owner, string message, BackgroundWorker worker)
{
...
}
private class WaitDialogCreator
{
static WaitDialogCreator() { }
internal static readonly WaitDialog uniqueInstance = new WaitDialog();
}
}
В моем методе ShowDialog () я могу передать параметр рабочего объекта, чтобы я мог установить некоторые свойства / обработчики, которые зависят от его свойств, такие как тип используемого индикатора выполнения (marquee, если он сообщает об изменениях прогресса, непрерывный в противном случае ), возможность отменить задачу (в соответствии с реквизитом WorkerSupportsCancellation) и т. д. Метод выглядит следующим образом:
public DialogResult ShowDialog(Form owner, BackgroundWorker worker)
{
if (worker == null)
{
throw new ArgumentNullException("worker", "A non-null worker must be provided.");
}
else
{
Instance.btnCancel.Enabled = worker.WorkerSupportsCancellation;
//This handler close the dialog
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(onWorkerWorkComplete);
if (worker.WorkerReportsProgress)
{
Instance.pbProgress.Style = ProgressBarStyle.Continuous;
//Update the progress bar
worker.ProgressChanged += new ProgressChangedEventHandler(onWorkerProgressChanged);
}
if (worker.WorkerSupportsCancellation)
{
Instance.btnCancel.Click += (sender, e) => { worker.CancelAsync(); };
}
}
return Instance.ShowDialog(owner);
}
Я бы получил доступ к диалоговому окну ожидания через контроллер в родительской форме следующим образом:
public Controller(Form window)
{
this.window = window;
this.waitDialog = WaitDialog.Instance;
}
...
public void ShowWaitDialog(BackgroundWorker worker)
{
if (worker == null)
{
this.ShowWaitDialog();
}
else
{
window.BeginInvoke((MethodInvoker)delegate() { waitDialog.ShowDialog(window, worker); });
}
}
Может быть, это очень нудистский вопрос, но вот он: правильно ли применять (как я) шаблон Singleton в этом случае, или я бы выбрал нормальное создание экземпляра, учитывая, что конец класса WaitDialog обычно обрабатывает больше чем BackGroundWorker в его жизненном цикле?
Меня удивляет то, что я могу (и я буду) изменять свойства отдельного экземпляра WaitDialog каждый раз, когда я передаю новый BackGroundWorker при вызове ShowDialog (Form, BackGroundWorker).
Это правильное поведение, в соответствии с шаблоном? Есть ли другой путь, который я могу выбрать для лучшей реализации? Я открыт для любых предложений.