2012-08-06 77 views
0

我试图绑定一些BindingListComboBox控制在我的WPF应用程序。但是,我的BindingList是从UI线程以外的其他线程更新的。更新BindingLIst绑定到组合框,从线程以外的其他线程

我组成了一个模型。所有你需要的是新的空项目,引用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线,它thorws一个例外:

这种类型的CollectionView不支持从一个线程从调度线程不同其 SourceCollection变化。

在真实的项目中,我不能将list.Add移动到UI线程,我想保留绑定问题。它如何解决?我可以转到其他“列表”,而不是BindingList。我尝试过简单的List<string>,但它更糟糕:当我添加新项目时,它根本不会更新。

编辑

在现实中,增加线程知道列表中,但它不知道WPF窗口。该列表与课堂内部工作相关,GUI将检查课程并查看它。所以,Add不应该知道GUI。

回答

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(); 

希望这有助于

+0

谢谢。我更新了这个问题。在现实中,添加线程知道列表,但它不知道WPF窗口。该列表与课堂内部工作相关,GUI将检查课程并查看它。所以,'Add'不应该知道GUI。 – 2012-08-06 12:23:30

+0

你应该使用像MVVM http://mvvmlight.codeplex.com/这样的设计模式。这很容易理解,远离你这样的问题。 – David 2012-08-06 12:41:29

0

UI线程被锁定。 然后你必须在一个特殊的功能中给你的数据。 MSDN BeginInvoke

使用:

BeginInvok(()=>{ // Your stuff}); 

你会问的UI尽快更新您的看法,因为它是有可能的。

+0

谢谢。我更新了这个问题。在现实中,添加线程知道列表,但它不知道WPF窗口。该列表与课堂内部工作相关,GUI将检查课程并查看它。所以,'Add'不应该知道GUI。 – 2012-08-06 12:23:12