我正在尝试在我的WPF应用中绑定一些BindingList
到ComboBox
控件。但是,我的BindingList
是从UI线程以外的其他线程更新的。
我编造了一个模型。您只需要新的空项目,引用WindowsBase,PresentationCore,PresentationFramework,System.Xaml(或者只是将其放入预定义的WPF窗口)。
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
public class MainWindow : Window
{
[STAThread]
public static void Main()
{
new MainWindow().ShowDialog();
}
public MainWindow()
{
BindingList<string> list = new BindingList<string>();
ComboBox cb = new ComboBox();
cb.SetBinding(ComboBox.ItemsSourceProperty, new Binding() { Source = list });
this.Content = cb;
list.Add("Goop");
new Thread(() =>
{
list.Add("Zoop");
}).Start();
}
}
在Goop
行中,一切正常。但是,当它到达Zoop
行时,会产生异常:
此类型的CollectionView不支持对其进行更改 来自与Dispatcher线程不同的线程的SourceCollection。
在真实项目中,我无法将list.Add
移动到UI线程,我想保留Binding问题。怎么解决?我可以转到其他“列表”而不是BindingList
。我尝试过简单的List<string>
,但情况更糟:当我添加新项目时它根本不会更新。
修改
实际上,添加线程知道列表,但它不知道WPF窗口。该列表在课堂上有内部工作,GUI检查类并查看它。因此,Add
不应该知道GUI。
答案 0 :(得分:0)
UI线程已锁定。 然后你必须在一个特殊的功能中提供你的数据。 MSDN BeginInvoke
使用:
BeginInvok(()=>{ // Your stuff});
您会要求用户界面尽快更新您的观看次数。
答案 1 :(得分:0)
试试这个,
new Thread(() =>
{
if (cb.Dispatcher.CheckAccess())
{
list.Add("Zoop");
}
else
{
cb.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate
{
list.Add("Zoop");
}
));
}
}).Start();
希望这会有所帮助