-
Prism v4: RegionContext lost when removing a view from a region
No CommentsThere have been some discussions in the Prism forums (for example this one and this one), where it was reported that removing a view that shares a region context with other views in a region, causes the region context in all the views in that region to be lost. This is because in the BindRegionContextToDependencyObjectBehavior, when a view is removed from a region, the DetachNotifyChangeEvent method is called after the SetContextToViews method, which is responsible for setting the view’s RegionContext attached property to null. Hence, the subscription to the ViewRegionContext_OnPropertyChangedEvent is not removed when the null value is set, and so this value will be spread to all the view’s RegionContext in that region, thus losing the region context data.
In this work item, the user mstrobel suggested that, by inverting the order of these method calls, in the BindRegionContextToDependencyObjectBehavior class from the Prism library, this problem is solved. We’ve reproduced a similar scenario, applying this workaround, and found that it worked correctly. Additionally, we thought of a possible way to achieve this without modifying the Prism source code, and we ended in the following sample (you can find it in my skydrive account, under the name RegionContextLostSample.)
In this sample, the implementation we used to extend this functionality is contained in the class BindRegionContextToDependencyObjectBehaviorWithFix, which is similar to the original behavior, but applies the aforementioned workaround:
1 (...) 2 private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 3 { 4 if (e.Action == NotifyCollectionChangedAction.Add) 5 { 6 SetContextToViews(e.NewItems, this.Region.Context); 7 this.AttachNotifyChangeEvent(e.NewItems); 8 } 9 10 else if (e.Action == NotifyCollectionChangedAction.Remove && this.Region.Context != null) 11 { 12 this.DetachNotifyChangeEvent(e.OldItems); 13 SetContextToViews(e.OldItems, null); 14 } 15 } 16 (...)Please note that, in order for this approach to work, you need to override the ConfigureDefaultRegionBehaviors method in your bootstrapper in order to replace the default implementation of the BindRegionContextToDependencyObjectBehavior with the aforementioned BindRegionContextToDependencyObjectBehaviorWithFix. Here is an example:
1 ConfigureDefaultRegionBehaviors() 2 { 3 var defaultRegionBehaviorTypesDictionary = ServiceLocator.Current.GetInstance<IRegionBehaviorFactory>(); 4 5 defaultRegionBehaviorTypesDictionary.AddIfMissing(BindRegionContextToDependencyObjectBehaviorWithFix.BehaviorKey, typeof(BindRegionContextToDependencyObjectBehaviorWithFix)); 6 7 return base.ConfigureDefaultRegionBehaviors(); 8 } 9Let me know if you have used it.
-
Leave a comment
Your email address will not be published.