Sync / Lock TwoWay Collection

What is the best way to synchronize two datasets using binding?

Target = Custom Setters - raises custom events whenever something changed Source = ObservableCollection - raises events whenever collection changed 

Now my question is: when I receive an update from one collection (for example, the Source.CollectionChanged event), I need to call custom TargetSetters and ignore the events raised from my update.

And also in another case, when custom Target events are fired, I need to update the source code, but ignore the CollectionChanged event.

At the moment, I keep a link to my handlers and delete it before updating any of the collections. eg.

 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; } 

I saw that you can use the if statement to check if the updates are source, and if they ignore them. eg.

 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; } 

After Google + SO Search came back with nothing, I wanted to see how other people do it, and is there something really simple, am I missing here that solves this problem? (I know that the examples are not thread safe)

If not, what is the preferred way? Removing and installing handlers or setting a boolean flag? Which is more productive (yes, I know that this is unlikely to cause a bottleneck, but out of curiosity)

The reason I'm asking for is because I am currently implementing Attached Behaviors and for each behavior, I am creating 2 sets of dictionaries that contain references to handlers for each object, since the state must be passed.

I cannot find the source code for the .NET binding class binding mechanism to see how MS implemented it. If anyone has a link to those, this will be very helpful.

+5
source share
1 answer

The mechanism you use, with a boolean that keeps track of when updates occur and blocks it, is the most common approach.

Personally, I prefer to port this logic to a small utility that implements IDisposable . This makes it easy to ensure that you always clean up after yourself.

A utility that you can use for this will look something like this:

 class Guard : IDisposable { readonly Func<bool> getter; readonly Action<bool> setter; readonly bool acquired = false; public Guard(Func<bool> getter, Action<bool> setter) { this.getter = getter; this.setter = setter; if (this.getter() == false) { this.setter(true); this.acquired = true; } } public bool Acquired { get { return this.acquired; } } void IDisposable.Dispose() { if (acquired) { this.setter(false); } } } 

Then you can write:

 private void ObservableCollection_OnCollectionChanged2(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) { using(var guard = new Guard(() => BindingTargetUpdating, v => BindingTargetUpdating = value)) { if (guard.Acquired) { // Do change logic and update Custom Object.... } } } 

This will not necessarily be shorter - it will probably take longer to write, but it guarantees that you will free your blocks if exceptions occur. You can always subclass Guard to reduce usage if you use it often.

+3
source

Source: https://habr.com/ru/post/1205737/


All Articles