I'm using Prism and the open source Prism interop library. I have a TabbedMdiHost in my applications Shell. The problem started when I implemented IRegionMemberLifetime.KeepAlive. When closing a tab that contains a view that returns false for KeepAlive, I get the following exception:
InvalidOperationException {"Cannot have nested BeginInit calls on the same instance."}
at System.Windows.FrameworkElement.BeginInit()
at System.Windows.Controls.ItemsControl.BeginInit()
at ActiproSoftware.Windows.Controls.Docking.DockingWindowContainer.BeginInit()
at ActiproSoftware.Windows.Controls.Docking.DockSite.#Lt(DependencyObject #lp)
at ActiproSoftware.Windows.Controls.Docking.DockSite.#uu(#ki #4j)
at ActiproSoftware.Windows.Controls.Docking.DockSite.#wu(DockingWindow #sb)
at ActiproSoftware.Windows.Controls.Docking.DockSite.#Cv(DockingWindow #sb, Boolean #zFf)
at ActiproSoftware.Windows.Controls.Docking.DockSite.#Su(IList`1 #BEd, IList #lF, Int32 #ahb, DockingWindowItemType #4Ub)
at ActiproSoftware.Windows.Controls.Docking.DockSite.#Ku(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at ActiproSoftware.Windows.EnumerableView`1.#Web(NotifyCollectionChangedEventArgs #yhb)
at ActiproSoftware.Windows.EnumerableView`1.#CM(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.DeferrableObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.RemoveItem(Int32 index)
at System.Collections.ObjectModel.Collection`1.RemoveAt(Int32 index)
at ActiproSoftware.Windows.EnumerableView`1.#aXb(Int32 #ahb, Int32 #LX)
at ActiproSoftware.Windows.EnumerableView`1.#9Wb(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegionViewsCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegionViewsCollection.OnEnumerableViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.EnumerableView`1.#Web(NotifyCollectionChangedEventArgs #yhb)
at ActiproSoftware.Windows.EnumerableView`1.#CM(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.DeferrableObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.RemoveItem(Int32 index)
at System.Collections.ObjectModel.Collection`1.RemoveAt(Int32 index)
at ActiproSoftware.Windows.EnumerableView`1.#aXb(Int32 #ahb, Int32 #LX)
at ActiproSoftware.Windows.EnumerableView`1.#9Wb(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at System.Collections.ObjectModel.ObservableCollection`1.RemoveItem(Int32 index)
at System.Collections.ObjectModel.Collection`1.Remove(T item)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegion.Remove(Object view)
at Microsoft.Practices.Prism.Regions.Behaviors.RegionMemberLifetimeBehavior.OnActiveViewsChanged(Object sender, NotifyCollectionChangedEventArgs e) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\RegionMemberLifetimeBehavior.cs:line 75
at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegionViewsCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegionViewsCollection.OnEnumerableViewCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.EnumerableView`1.#Web(NotifyCollectionChangedEventArgs #yhb)
at ActiproSoftware.Windows.EnumerableView`1.#CM(Object #xhb, NotifyCollectionChangedEventArgs #yhb)
at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.DeferrableObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
at ActiproSoftware.Windows.DeferrableObservableCollection`1.EndUpdate()
at ActiproSoftware.Windows.EnumerableView`1.#bXb(Int32 #ahb, T #G3, Boolean #JJf)
at ActiproSoftware.Windows.EnumerableView`1.ReevaluateAt(Int32 index)
at ActiproSoftware.Windows.EnumerableView`1.Reevaluate(T item)
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegionViewsCollection.OnItemMetadataChanged(Object sender, EventArgs e)
at System.EventHandler.Invoke(Object sender, EventArgs e)
at Microsoft.Practices.Prism.Regions.ItemMetadata.InvokeMetadataChanged() in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\ItemMetadata.cs:line 86
at Microsoft.Practices.Prism.Regions.ItemMetadata.DependencyPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\ItemMetadata.cs:line 94
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at Microsoft.Practices.Prism.Regions.ItemMetadata.set_IsActive(Boolean value) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\ItemMetadata.cs:line 72
at ActiproSoftware.Windows.Prism.Regions.DockSiteRegion.Deactivate(Object view)
at ActiproSoftware.Windows.Prism.Regions.Behaviors.DockSiteRegionBehavior.OnDockSiteWindowDeactivated(Object sender, DockingWindowEventArgs e)
Here's what's in the my application's main shell Window
<docking:DockSite x:Name="dockSite"
prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainRegion}"
CanDocumentWindowsRaft="True"
CanToolWindowsRaft="True">
<docking:Workspace>
<docking:TabbedMdiHost x:Name="tabbedMdiHost">
<docking:TabbedMdiContainer>
</docking:TabbedMdiContainer>
</docking:TabbedMdiHost>
</docking:Workspace>
</docking:DockSite>
Views are added to my region like so.. (this is all standard stuff)
BitmapImage image = new BitmapImage(new Uri(file));
ImageViewModel viewModel = new ImageViewModel() { Image = image };
var regionManager = (IRegionManager)ServiceLocator.Current.GetInstance<IRegionManager>();
regionManager.Regions[RegionNames.MainRegion].Add(new ImageView() { ImageViewModel = viewModel });
For some reason, removing my ImageView (which is very simple and only contains only an image) works, but other views do not. Here's an example of a view that is successfully removed with I click the X on the tab. (all my view's implement DockingViewBase which implements IRegionMemberLifetime, IActiveAware, IDockingWindowInitializer, and IDockingWindowItemTypeProvider. They should supply the exact same values for both these views)
<local:DockingViewBase x:Class="Project.Infrastructure.Views.ImageView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Project.Infrastructure.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="{Binding Path=Image.UriSource.LocalPath}">
<Image Name="image1" Source="{Binding Image}" HorizontalAlignment="Center" VerticalAlignment="Center"
StretchDirection="DownOnly" />
</local:DockingViewBase>
Here's an example of one that fails with the exception above:
<inf:DockingViewBase x:Class="Project.Module.Views.ViewExample2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="249" d:DesignWidth="569"
Title="{Binding Path=Signals.Name}">
<Grid>
<DataGrid ItemsSource="{Binding Signals}" AutoGenerateColumns="False">
<DataGrid.Resources>
<conv:FrequencyStringConverter x:Key="FrequencyConverter"/>
<conv:DecibelStringConverter x:Key="DecibelConverter"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Frequency" Binding="{Binding Frequency, Converter={StaticResource FrequencyConverter}}"/>
<DataGridTextColumn Header="Bandwidth" Binding="{Binding Bandwidth, Converter={StaticResource FrequencyConverter}}"/>
<DataGridTextColumn Header="Amplitude" Binding="{Binding Amplitude, Converter={StaticResource DecibelConverter}}"/>
<DataGridTextColumn Header="Comments" Binding="{Binding Comments}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</inf:DockingViewBase>
Any idea what's going on? Why is BeginInit being called when I'm closing something? How can I fix it?
[Modified 12 years ago]