[英]Understanding Delegates
这不是我第一次遇到代表,而且我和上次以及之前的时间一样困惑。 因此,我一劳永逸地想要彻底清除delgate混乱。
我的问题如下
有一个图形用户界面只显示带有一些boud项目的ListView,我想从数据连接加载数据,这需要一些时间,以增加使用我已实现BackgroundWorker的应用程序的舒适度和doWork方法我想要获取数据并显示它。
这就是我想要的
现在这是Cross-Thread-Invoking,我想通过Delegates来解决这个问题。 在本教程之后 ,我得到了一个有效的委托, 但它没有解决问题,在我的委托中我无法更改我的ListView,它仍然说它在另一个线程上。
我想找到一个关于代表的Easy explenation以及如何使用它们来解决我的问题。 另外,我应该考虑或设计不同的软件吗?
通常, BackgroundWorker
使用ReportProgress
与UI线程进行通信。 您可以在启动后台工作程序之前挂钩委托以接收这些进度事件,然后在UI线程上报告进度,您可以安全地更改ListView
。
Windows窗体中的另一个替代方法是调用Control.Invoke
或Control.BeginInvoke
,传入将更新UI的委托。 该委托将在UI线程上执行。 有关此示例,请参阅我的线程教程或Joe Albahari的 。
在WPF中相当于Dispatcher
- 再次, Invoke
和BeginInvoke
。 您可以使用Dispatcher
属性访问控件的Dispatcher
。
您无法直接从其他线程更改ui控件,需要在进行更改之前检查Control.InvokeRequired
属性。
在msdn上查看此示例
查看此代码,它可以满足您的需求:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnFill_Click(object sender, EventArgs e)
{
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerAsync();
}
private delegate void AddItemToListViewDelegate(ListView view, ListViewItem item);
private void AddItemToListView(ListView view, ListViewItem item)
{
if (InvokeRequired)
{
Invoke(new AddItemToListViewDelegate(AddItemToListView), new object[] { view, item });
return;
}
view.Items.Add(item);
}
private delegate void ClearListViewItemsDelegate(ListView view);
private void ClearListView(ListView view)
{
if (InvokeRequired)
{
Invoke(new ClearListViewItemsDelegate(ClearListView), new object[] { view });
return;
}
view.Items.Clear();
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
if (i == 0)
ClearListView(listView1);
var item = new ListViewItem();
item.Name = i.ToString();
item.Text = item.Name;
AddItemToListView(listView1, item);
}
}
}
对于WPF,需要类似的东西。 请注意,这不是有效的代码。 由于我不使用WPF,我不能保证这是可靠的代码,但它应该给你一个想法。 您可能需要创建一个派生自EventArgs的类型来封装listview和listviewitems。
如果我有时间,我会编辑这篇文章,以便它可以工作,但那将要等到今晚!
using System.Windows.Threading;
...
if (listView1.Dispatcher.Thread != Thread.CurrentThread)
{
listView1.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new EventHandler<ListViewAddEventArgs>(AddItemToListView), sender, new object[] { e } );
return;
}
listView1.Items.Add(e.File);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.