在一个虚拟的WinForms应用程序中,我能够在设计时创建一个ListBox,在运行时创建一个后台线程,然后从后台线程向ListBox添加控件。但如果我在WPF中做同样的事情,就会出现错误。
为什么我能在WinForms中做到这一点,但在WPF中却不能?我的WinForm示例和WPF示例不同吗?或者确实有一个原因,它在WinForms中可以正常工作而在WPF中不行?
WinForms:
我收到的错误信息是标准和预期的,如下图所示:
为什么我能在WinForms中做到这一点,但在WPF中却不能?我的WinForm示例和WPF示例不同吗?或者确实有一个原因,它在WinForms中可以正常工作而在WPF中不行?
WinForms:
private List<Label> _labels;
public Form1()
{
InitializeComponent();
Thread test = new Thread(DoStuff);
test.SetApartmentState(ApartmentState.STA);
test.Start();
}
private void DoStuff()
{
_labels = new List<Label>();
_labels.Add(new Label() { Text = "Label1" });
_labels.Add(new Label() { Text = "Label2" });
_labels.Add(new Label() { Text = "Label3" });
if (listBox1.InvokeRequired)
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.DataSource = _labels; });
}
else
{
listBox1.DataSource = _labels;
}
}
WPF:
public partial class MainWindow : Window
{
private ObservableCollection<Label> _labels;
public MainWindow()
{
InitializeComponent();
Thread test = new Thread(DoStuff);
test.SetApartmentState(ApartmentState.STA);
test.Start();
}
private void DoStuff()
{
_labels = new ObservableCollection<Label>();
_labels.Add(new Label() { Content = "Label1" });
_labels.Add(new Label() { Content = "Label2" });
_labels.Add(new Label() { Content = "Label3" });
this.Dispatcher.BeginInvoke((Action)(() =>{ icMain.ItemsSource = _labels; }));
}
}
我收到的错误信息是标准和预期的,如下图所示:
listBox1.Invoke(...)
确保传递的委托在UI线程上调用。 - user743382_labels
不是用户界面元素,List<T>
和ObservableCollection<T>
也没有这样的跨线程检查(除了可能存在并发访问),所以如果它引起任何混淆,那会让我感到惊讶,但你可能是正确的。 - user743382