我正在研究一個應用程序,該應用程序具有底部狀態欄的主窗體。狀態欄包含一個ProgressBar和一個標籤,我想用它來向用戶顯示正在完成的一些工作的當前進度。狀態欄還包含一個我想要使用的標籤,如可點擊取消按鈕。將接口概括爲GUI中的進度條
我已經創建了類似這樣的異步接口,但他們一直基於一個動作,並且使用後臺工作。但是,在這個新程序中,用戶可能會啓用許多不同的操作,我希望使用同一個狀態欄來顯示所有這些操作的進度。所以我試圖找出一種方法來概括和標準化狀態欄中這些進度報告控件的界面。
在某些情況下,異步進程是使用BackGroundWorker創建的,但在其他情況下,我需要直接創建管理輔助線程。
下面是一些半成品的骨架代碼是我一直在想:
public partial class MyForm: System.Windows.Forms.Form
{
...SNIP...
private void WorkProgressChanged(Object sender, EventArgs args)
{
ProgressChangedEventArgs backgroundWorkerArgs = args as ProgressChangedEventArgs;
ProgressReport formReport = args as ProgressReport; //my own custom progress report class
//tries to cast args to a Background worker args
if (backgroundWorkerArgs != null)
{
// update UI based on backgroundWorkerArgs
}
else if (formReport != null)
{
// update UI basd on formReport
}
else
{
//couldn't figure out what kind of progress report was sent
//update UI based on args.ToString();
}
}
private void cancelButtonToolStripLabel_Click(object sender, EventArgs e)
{
//calls cancel method of current processing
if (this._currentWorkCancelAction != null)
{
_currentWorkCancelAction(); //envoke cancel requet
cancelButtonToolStripLabel.Text = "Canceling"; //shows user that cancel request was made
_currentWorkCancelAction = null; //disaccociates cancel button to prevent user from canceling twice
}
}
private void WorkProcessCompleted(Object sender, EventArgs args)
{
//Reset cancel button
cancelButtonToolStripLabel.Text = "Cancel";
cancelButtonToolStripLabel.Visible = false;
//resets the status label and progress bar
statusToolStripLabel.Text = "";
toolStripProgressBar.Value = 0;
}
....SNIP
}
所以狀態欄訂閱`WorkProgressChanged(對象發件人,EventArgs參數)的一些事情 更新」,並最終當'WorkProcessCompleted(Object sender,EventArgs args)'被完成甚至包含時,重置。我的取消標籤(按鈕)也需要關聯,並在稍後與委託方法分離,該方法將要求取消當前正在進行的任何工作。
因此,每次完成工作都需要發生一堆事情。事件訂閱被添加/刪除,委託引用被改變等等..等等。所以我開始想知道是否有某種方式可以將所有這些動作封裝到一個或兩個可重用的方法中,而不是爲可能需要的每個動作編寫重複的代碼地點。
下面的InitWorkProcess()
方法顯示了我如何認爲這可能工作。雖然我很確定這不是使用EventDescriptor類的正確方法。我找不出任何其他方式將事件引用爲方法參數。也許這是不可能的?
public void InitWorkProcess(EventDescriptor workProgressChangedEvent, EventDescriptor workCompletedEvent, System.Action requestCancel)
{
//subscribe to progress changed
workProgressChangedEvent.AddEventHandler(this, this.WorkProgressChanged);
this._workProgressChangedEvent = workProgressChangedEvent;
//subscribe to process completed
workCompletedEvent.AddEventHandler(this, this.WorkProcessCompleted);
this._workCompletedEvent = workCompletedEvent;
//enable cancel button
if (requestCancel != null)
{
cancelButtonToolStripLabel.Visible = true;
this._currentWorkCancelAction = requestCancel;
}
}
...我會更改WorkProgressComplete事件處理方法,以在工作完成時取消訂閱事件關係。
private void WorkProcessCompleted(Object sender, EventArgs args)
{
//Reset cancel button
cancelButtonToolStripLabel.Text = "Cancel";
cancelButtonToolStripLabel.Visible = false;
//resets the status label and progress bar
statusToolStripLabel.Text = "";
toolStripProgressBar.Value = 0;
//unsubscribes WorkProcessCompleted() and WorkProgressChanged() methods
this._workCompletedEvent.RemoveEventHandler(this, this._workCompletedEvent);
this._workCompletedEvent = null;
this._workProgressChangedEvent.RemoveEventHandler(this, this._workProgressChangedEvent);
this._workProgressChangedEvent = null;
}
有沒有人有任何建議,我應該如何設置?我應該忘記InitWorkProcess()
方法,而是分別爲每個操作添加/刪除所有事件/委託關係?或者有更好的方法嗎?
我不知道,好點。儘管我認爲我最終會遇到同樣的問題,因爲即使我將其限制爲ProgressChangedEventArgs,也沒有限制實際用於其UserState屬性的類型。 – 2010-02-25 02:17:39
好的,您可以在UserState屬性中使用一致的數據類型,並使用'as'關鍵字來安全地轉換爲該類型。如果它爲null,則可以將該事件忽略爲未知進度事件。否則,您可以對任何來源的所有進度事件使用單個實現。 – jrista 2010-02-25 02:26:26