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

时间:2015-08-20 18:47:39

标签: c# wpf data-binding

在XAML中有这样的绑定:

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

我想从源(ErrorList)“拦截”更新到目标并运行我自己的代码。例如,我可能想要阻止绑定发生。或者,在我的实际情况中,我想使用窗口的调度程序更新绑定(因为ErrorList在另一个线程中被更改)。

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

2 个答案:

答案 0 :(得分:1)

假设您希望根据某些业务规则更新目标,请添加如下所示的属性

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

在您需要的时间和地点更新您的私有对象_activeListDocument,然后致电NotifyPropertyChanged("ErrorList");更新您的目标。

答案 1 :(得分:1)

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