【发布时间】:2014-12-24 13:32:38
【问题描述】:
通过 Binding 同步 2 组数据的最佳方式是什么?
Target = Custom Setters - raises custom events whenever something changed
Source = ObservableCollection - raises events whenever collection changed
现在我的问题是,当我收到来自一个集合的更新(例如 Source.CollectionChanged 事件)时,我需要调用自定义 TargetSetters,并忽略源自我的更新的调用事件。
另一方面,当 Target 自定义事件被触发时,我需要更新源,但忽略 CollectionChanged 事件。
目前,我保留对我的处理程序的引用,并在更新任何集合之前将其删除。例如
private void ObservableCollection_OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
CustomObject.SelectionChanged -= CustomObject_SelectionChanged;
// Do change logic and update Custom Object....
CustomObject.SelectionChanged += CustomObject_SelectionChanged;
}
void CustomObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ObservableCollection.CollectionChanged -= ObservableCollection_OnCollectionChanged;
// Do change logic and update ObservableCollection...
ObservableCollection.CollectionChanged += ObservableCollection_OnCollectionChanged;
}
我看到您可以使用 if 语句来检查更新是否来自源,以及是否忽略它们。例如
private void ObservableCollection_OnCollectionChanged2(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
if (BindingTargetUpdating) return;
BindingSourceUpdating = true;
// Do change logic and update Custom Object....
BindingSourceUpdating = false;
}
void CustomObject_SelectionChanged2(object sender, SelectionChangedEventArgs e)
{
if (BindingSourceUpdating) return;
BindingTargetUpdating = true;
// Do change logic and update ObservableCollection...
BindingTargetUpdating = false;
}
在 Google + SO 搜索一无所获后,我想看看其他人是如何做到这一点的,我在这里缺少什么真正简单的东西可以解决这个问题吗? (我知道这些例子不是线程安全的)
如果不是,首选的方法是什么?删除和附加处理程序,或设置布尔标志?什么性能更高(是的,我知道这极不可能导致瓶颈,但出于好奇)
我问的原因是,目前我正在实现附加行为,并且对于每个行为,我正在创建 2 组字典,它们保存对每个对象的处理程序的引用,因为必须传递状态。
我似乎找不到 .NET Binding 类的绑定机制的源代码,看看 MS 是如何实现它的。如果有人有这些链接,将不胜感激。
【问题讨论】:
-
抱歉,我可能遗漏了一些东西,但为什么您的设计要求您忽略每次发生变化时触发的一些事件?我真的无法弄清楚你想要完成什么。您能否说明您要解决的问题是什么?
-
因为如果你订阅双方,你会收到双方的通知。导致无限循环。例如。 Customibject 引发它更改的事件,我的处理程序被调用并更改绑定的集合,这反过来引发更改的事件,因此我的集合更改处理程序被调用,它编辑自定义对象。然后这再次引发事件,你在一个循环中
-
是的,我的意思是,在设计程序时必须故意阻止它进入无限循环,这是一种相当大的代码味道。您是否有理由不只是通过 INotifyPropertyChanged 处理对集合的更改,还是我误解了您的目的?
-
它们由 INotifyPropertyChanged 处理,我需要将 DataGrid.SelectedCells、ScrollViewer.HorizontalOffset/ScrollViewer.VerticalOffset 绑定到 TwoWay 可观察集合/对象。所有这些属性都是只读的,所以不,普通绑定不起作用,它可能以一种方式起作用,但我需要将更新从我的 ViewModel 推送到我的 View
-
我通常看到这是通过标志或某种
using范围设备完成的。
标签: c# .net wpf binding synchronization