2012-08-06 38 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