我实际上在学习(艰难的方式)C#,并为问题困扰了好几天:
我正在用WPF(dotNet 4.0)编写我的第一个C#应用程序。当我单击按钮时,将使用BackgroundWorker线程并从外部类调用方法,这样我的UI不会冻结->我的方法按预期运行。
然后,我尝试从外部类更新ListView控件以获取某种进度(文本),但不幸的是失败了。
我知道我需要使用委托和调度程序来更新我的控件。
我尝试使用此处提供的解决方案:如何从另一个类中运行的另一个线程更新UI。(由于声望低,我无法对此发表评论),而且我错过了拼图的某些部分。
什么YourEventArgs(状态)是指什么?当我的方法在BGW中运行时,我只是没有办法触发事件并将内容传递回我的UI。
到目前为止,我有这段代码(从answer更新):
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; }
}
}
谢谢你的帮助。
您可以简单地ProgressUpdate
从FlushData()
方法中调用事件。
只需致电:
If (ProgressUpdate !=null )
{
ProgressUpdate(this,new YourEventArgs())
}
this
是源实例的来源实例event
。
您可以通过从EventArgs
类继承来创建YourEventArgs 。
public class YourEventArgs : EventArgs
{
//Put any property that you want to pass back to UI here.
}
当event
在UI中引发时:
RaiseEvent.ProgressUpdate += (s, e) =>
{
Dispatcher.BeginInvoke((Action)(() =>
{
lstTest.Items.Add("this is a test : ");
//Add items to your UI control here...
}));
};
e将为类型YourEventArgs
。
顺便提一句,您永远不要触摸其他线程(例如您的示例中的背景工作线程)中的UI线程。由于您event-handler
已经执行过Dispatcher.BeginInvoke
,所以很安全。
同样,您的ProgressUpdate
事件应该在类SetXmlData中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句