如何拦截从源到目标的绑定

本文关键字:目标 绑定 何拦截 | 更新日期: 2023-09-27 18:09:10

在XAML中使用这样的绑定:

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

我想"拦截"从源(ErrorList)到目标的更新并运行我自己的代码。例如,我可能希望防止绑定发生。或者,在我的实际情况中,我想使用窗口的调度程序更新绑定(因为ErrorList在不同的线程中更改)。

有趣的是,我可以通过将UpdateSourceTrigger设置为Explicit来指定我想手动更新源,但是没有类似的属性来指定我想要显式更新目标。

如何拦截从源到目标的绑定

假设您希望基于某些业务规则更新目标,那么添加如下属性

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

更新您的私有对象_activeListDocument何时何地需要,然后调用NotifyPropertyChanged("ErrorList");更新您的目标。

您可以在BindingExpression上使用UpdateTarget,并将绑定的Mode设置为One Time。但是从你的问题看来,你是从后台线程访问Errorlist(收集错误消息?)你也可以使用绑定上的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);
    }
}