Hi,
I have previously been changing ApplicationTheme at runtime, successfully, by re-adding my main control. This causes a number of problems. Recently I started getting a strange scenario.
My MainView defines Prism Regions, removing it and re-adding it causes those regions to be removed and readded. I also have a docking control and am using the RadPaneGroupRegionAdapter as suggested in your blogs.
As I re-add the main view, (with it's associated regions), the region manager correctly starts re-adding the child views. The Adapt method is called in RadPaneGroupRegionAdapter (as expected) to re-add the associated RadPanes.
The Views.CollectionChanged event fires, calling the lambda expression with an Action of NotifyCollectionChangedAction.Add, to re-add the old views - again as expected.
The problem is these views were previously associated with a docking control from the old control that is no longer present, therefore their parent is not null. Calling regionTarget.Items.Add(item) therfore crashes as the item already belongs to another collection.
The solution appears to be -
Unfortunately, the RemoveFromParent throws an exception:
{System.Exception: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.FrameworkElement_SetStyleValue(FrameworkElement doh, DependencyProperty property, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.ClearValueInternal(DependencyProperty dp)
at System.Windows.DependencyObject.ClearValue(DependencyProperty dp)
at Telerik.Windows.Controls.RadPaneGroup.RemovePane(RadPane pane)
at Telerik.Windows.Controls.RadPane.RemoveFromParent()
at WebApplications.Siverlight.PrismExtensions.Regions.RadPaneGroupRegionAdapter.<>c__DisplayClass2.<Adapt>b__0(Object s, NotifyCollectionChangedEventArgs e)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.AddAndNotify(IList items)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.UnderlyingCollection_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at Microsoft.Practices.Composite.Presentation.Regions.Region.InnerAdd(Object view, String viewName, IRegionManager scopedRegionManager)
at Microsoft.Practices.Composite.Presentation.Regions.Region.Add(Object view, String viewName, Boolean createRegionManagerScope)
at Microsoft.Practices.Composite.Presentation.Regions.Region.Add(Object view)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.AddViewIntoRegion(Object viewToAdd)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.StartPopulatingContent()
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.OnAttach()
at Microsoft.Practices.Composite.Presentation.Regions.RegionBehavior.Attach()
at Microsoft.Practices.Composite.Presentation.Regions.RegionBehaviorCollection.Add(String key, IRegionBehavior regionBehavior)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.AttachDefaultBehaviors(IRegion region, T regionTarget)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.Initialize(T regionTarget, String regionName)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.Microsoft.Practices.Composite.Regions.IRegionAdapter.Initialize(Object regionTarget, String regionName)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.DelayedRegionCreationBehavior.CreateRegion(DependencyObject targetElement, String regionName)}
Possibly because the parent is unloaded? It doesn't set the items parent to null first either, so even if you catch the error, the corresponding Add still fails. Obviously the problem seems to be that under certain scenarios Prism doesn't tell the adapter about region removals. However, it is only the adapter that fails under those scenarios, suggesting that there is a slight design issue - an assumption is being made that you are always told when views are removed from a region?
Thanks
I have previously been changing ApplicationTheme at runtime, successfully, by re-adding my main control. This causes a number of problems. Recently I started getting a strange scenario.
My MainView defines Prism Regions, removing it and re-adding it causes those regions to be removed and readded. I also have a docking control and am using the RadPaneGroupRegionAdapter as suggested in your blogs.
As I re-add the main view, (with it's associated regions), the region manager correctly starts re-adding the child views. The Adapt method is called in RadPaneGroupRegionAdapter (as expected) to re-add the associated RadPanes.
The Views.CollectionChanged event fires, calling the lambda expression with an Action of NotifyCollectionChangedAction.Add, to re-add the old views - again as expected.
The problem is these views were previously associated with a docking control from the old control that is no longer present, therefore their parent is not null. Calling regionTarget.Items.Add(item) therfore crashes as the item already belongs to another collection.
The solution appears to be -
if (item.Parent != null) |
item.RemoveFromParent(); |
regionTarget.Items.Add(item); |
Unfortunately, the RemoveFromParent throws an exception:
{System.Exception: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.FrameworkElement_SetStyleValue(FrameworkElement doh, DependencyProperty property, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.ClearValueInternal(DependencyProperty dp)
at System.Windows.DependencyObject.ClearValue(DependencyProperty dp)
at Telerik.Windows.Controls.RadPaneGroup.RemovePane(RadPane pane)
at Telerik.Windows.Controls.RadPane.RemoveFromParent()
at WebApplications.Siverlight.PrismExtensions.Regions.RadPaneGroupRegionAdapter.<>c__DisplayClass2.<Adapt>b__0(Object s, NotifyCollectionChangedEventArgs e)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.AddAndNotify(IList items)
at Microsoft.Practices.Composite.Presentation.Regions.ViewsCollection.UnderlyingCollection_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
at System.Collections.ObjectModel.Collection`1.Add(T item)
at Microsoft.Practices.Composite.Presentation.Regions.Region.InnerAdd(Object view, String viewName, IRegionManager scopedRegionManager)
at Microsoft.Practices.Composite.Presentation.Regions.Region.Add(Object view, String viewName, Boolean createRegionManagerScope)
at Microsoft.Practices.Composite.Presentation.Regions.Region.Add(Object view)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.AddViewIntoRegion(Object viewToAdd)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.StartPopulatingContent()
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.AutoPopulateRegionBehavior.OnAttach()
at Microsoft.Practices.Composite.Presentation.Regions.RegionBehavior.Attach()
at Microsoft.Practices.Composite.Presentation.Regions.RegionBehaviorCollection.Add(String key, IRegionBehavior regionBehavior)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.AttachDefaultBehaviors(IRegion region, T regionTarget)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.Initialize(T regionTarget, String regionName)
at Microsoft.Practices.Composite.Presentation.Regions.RegionAdapterBase`1.Microsoft.Practices.Composite.Regions.IRegionAdapter.Initialize(Object regionTarget, String regionName)
at Microsoft.Practices.Composite.Presentation.Regions.Behaviors.DelayedRegionCreationBehavior.CreateRegion(DependencyObject targetElement, String regionName)}
Possibly because the parent is unloaded? It doesn't set the items parent to null first either, so even if you catch the error, the corresponding Add still fails. Obviously the problem seems to be that under certain scenarios Prism doesn't tell the adapter about region removals. However, it is only the adapter that fails under those scenarios, suggesting that there is a slight design issue - an assumption is being made that you are always told when views are removed from a region?
Thanks