2009-08-05 77 views
1

有什麼辦法怎麼辦WPF ICollectionView刷新

ICollectionView.Refresh() 
單獨的線程

CollectionViewSource.GetDefaultView(args.NewValue).Refresh(); 

我知道我可以使用調度程序,但是這個集合綁定到一個ListView,並且它引發了跨線程異常。

我需要第二個線程的原因是,我有控制顯示IMyItems列表。當過濾此Collection(通過用戶文本更改輸入)時,我希望能夠顯示CollectionView正在更改的動畫。

+0

如果您希望在用戶輸入過程中對其進行過濾,您應該能夠在開始輸入時顯示動畫(例如開始故事板) - 不需要第二個線程。 – 2009-08-06 13:42:40

回答

3

你不能!

所有的UI操作必須發生在用戶界面線程,和WPF的DispatcherObject的(在該層次結構的所有控件)內幾乎每一個電話經常會被調用的checkAccess()。

如果您正在後臺線程或BackgroundWorker中處理數據,您可能需要考慮使用ObservableCollection來幫助保持數據最新。

-2

我設計了一個簡單快捷的方法來調用WPF分派對象的動作(所有WPF控件從DispatcherObject繼承)

public static void InvokeWpf(DispatcherObject dispatchable, Action action, bool async) 
{ 
    // DispatcherOperationCallback is optimized for wpf invoke calls 
    DispatcherOperationCallback toDo = delegate{ action(); return null; }; 

    if (!dispatchable.CheckAccess()) 
    { 
     if (async) 
      dispatchable.Dispatcher.BeginInvoke(toDo, null); 
     else 
      dispatchable.Dispatcher.Invoke(toDo, null); 
    } 
    else 
    { 
     toDo(null); 
    } 
} 

用法:

InvokeWpf(listView, 
     () => CollectionViewSource.GetDefaultView(listView).Refresh(), 
     false); 
+0

我試過你的解決方案(我已經提出了你的建議)..但無論如何它運行在同一個線程中... – 2009-08-05 12:32:33

+1

DispatcherOperationCallback以何種方式進行了優化? 它只是一個代表。既然你已經有了這個「行動」的委託,把它包裝在另一個委託中只是浪費空間和可讀性。 – 2011-09-19 16:25:06

3

如何使用分派做工作,背景優先?

Dispatcher.Invoke(DispatcherPriority.Background, 
    () => { CollectionViewSource.GetDefaultView(args.NewValue).Refresh(); } 
); 
+0

但新值綁定到ListView ..不會拋出異常嗎?這個線程不是所有者? – 2009-08-05 12:41:20