2015-08-20 61 views
0

有一個像這樣的XAML綁定:如何攔截從源到目標的綁定?

<ItemsControl 
    ItemsSource="{Binding ErrorList}" 
    /> 

我想「攔截」了從源(ErrorList)的目標更新和運行自己的代碼。例如,我可能想要防止發生綁定。或者,在我的實際情況中,我想使用窗口的調度程序更新綁定(因爲ErrorList在不同的線程中更改)。

有趣的是,我可以指定我想通過將UpdateSourceTrigger設置爲Explicit來手動更新源,但是沒有類似的屬性來指定我希望顯式更新目標。

+1

你可以做,通過增加一個私有變量來設置視圖模型的值,然後,如果任何改變都需要進行更新,你可以觸發事件OnPropertyChanged。 –

+1

一種方法是創建自定義標記擴展。這裏人創建延遲綁定http://paulstovell.com/blog/wpf-delaybinding – wiero

回答

1

比方說,你要基於一些業務規則,更新的目標,所以加的屬性如下圖所示,

private List<Error>_ErrorList; 
    public List<Error> ErrorList 
    { 
     get { return _ErrorList; } 
     set 
     { 
      _ErrorList= value;     
     } 
    } 

更新您的私有對象_activeListDocument何時何地您需要,然後調用NotifyPropertyChanged("ErrorList");更新目標。

+0

這是一個很好的解決方案,但你認爲有一種方法可以讓視圖模型完全不知道如何處理綁定?換句話說,我可以在不修改視圖模型的情況下做我想做的事嗎?對於我的問題中的示例,視圖模型包含一個名爲'ErrorList'的ObservableCollection,因此更新是通過收集已更改的事件完成的。 – redcurry

+0

@redcurry我不認爲這將是一個很好的解決方案。因爲如果我們不讓ViewModel知道View的含義,那麼View和ViewModel概念就會崩潰。 –

+0

的確如此,儘管ViewModel並不瞭解View的MVVM概念嗎? – redcurry

1

您可以在BindingExpression上使用UpdateTarget並將綁定的Mode設置爲One Time。但是從你的問題看來,你是從後臺線程訪問錯誤列表(收集錯誤消息?),你也可以在綁定上使用EnableCollectionSynchronization來處理這個問題。

如果您可以放棄線程安全要求,則以下操作可以添加跨線程通知。

public class SynchronizedObservableCollection<T> : ObservableCollection<T> 
{ 
    private SynchronizationContext synchronizationContext; 

    public SynchronizedObservableCollection() 
    { 
     synchronizationContext = SynchronizationContext.Current; 
    } 

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     synchronizationContext.Send((object state) => base.OnCollectionChanged(e), null); 
    } 

    protected override void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     synchronizationContext.Send((object state) => base.OnPropertyChanged(e), null); 
    } 

    protected override void ClearItems() 
    { 
     synchronizationContext.Send((object state) => base.ClearItems(), null); 
    } 

    protected override void InsertItem(int index, T item) 
    { 
     synchronizationContext.Send((object state) => base.InsertItem(index, item), null); 
    } 

    protected override void MoveItem(int oldIndex, int newIndex) 
    { 
     synchronizationContext.Send((object state) => base.MoveItem(oldIndex, newIndex), null); 
    } 

    protected override void RemoveItem(int index) 
    { 
     synchronizationContext.Send((object state) => base.RemoveItem(index), null); 
    } 

    protected override void SetItem(int index, T item) 
    { 
     synchronizationContext.Send((object state) => base.SetItem(index, item), null); 
    } 
} 
+0

'EnableCollectionSynchronization'似乎是我所需要的,除了我被限制爲使用.NET 4.0。 – redcurry

+0

如果您無法更改視圖模型並且您的視圖模型不是線程安全的...... – Wouter