實際上我學習(艱難地),C#和被一個問題爭取天:C# - 如何從一個線程在另一個類更新主UI
我用WPF寫我的第一個C#應用程序(dotNet 4.0)。當我點擊一個按鈕時,會使用BackgroundWorker線程並從外部類調用一個方法,這樣我的UI就不會凍結 - >我的方法按預期運行。
然後我試圖從thos外部類更新一個ListView控件來獲得某種進度(文本),我悲慘地失敗了。
我知道我需要使用委託和調度程序來更新我的控件。
我試着用這裏提供的解決方案How to update UI from another thread running in another class。 (我不能評論它,因爲我的代表低),我想念一些難題。
什麼YourEventArgs(狀態)是指?當我的方法在BGW中運行時,我只是無法啓動事件並將內容傳回給我的用戶界面。
到目前爲止,我有這段代碼(從答案更新):
namespace AppMain
{
public partial class MainWindow
{
BackgroundWorker AppWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
AppWorker.WorkerSupportsCancellation = true;
AppWorker.DoWork += AppWorker_DoWork;
AppWorker.RunWorkerCompleted += AppWorker_RunWorkerCompleted;
}
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
lstTest.Items.Add("Processing data...");
AppWorker.RunWorkerAsync();
}
public void AppWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
SetXmlData xml = new SetXmlData();
xml.ProgressUpdate += (s, evt) =>
{
Dispatcher.BeginInvoke((Action)(() =>
{
lstTest.Items.Add("this is a test : " + evt.myData); //how to retrieve the myData property from evt ?
}));
};
xml.FlushData();
}
public void AppWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (!(e.Cancelled))
{
lstTest.Items.Add("Done");
}
else
{
MessageBox.Show("Cancelled");
}
}
}
}
SetXmlData.cs
namespace AppMain
{
public class SetXmlData
{
public event EventHandler ProgressUpdate;
//update method
public void update(object input)
{
if (ProgressUpdate != null)
ProgressUpdate(this, new YourEventArgs { myData = (string)input });
}
//calculation method
public void FlushData()
{
MessageBox.Show("this is a test !");
update("test");
}
}
public class YourEventArgs : EventArgs
{
public string myData { get; set; }
}
}
感謝您的幫助。
相關,可能重複:http://stackoverflow.com/questions/11625208/accessing-ui-main-thread-safely- in-wpf – jdphenix
如果在.net 4.0中有任務,可以通過當前同步上下文在? – VMAtm
我剛開始時使用了這個功能,但後來爲了ReportProgress功能而轉移到了BGW,最後你是對的,這不是更好,當我解決這個問題時,我會切換回任務。 – Coloris