Search code examples
c#xamlbindingwindows-phone-8itemscontrol

ItemsControl Element is already the child of another element


I am trying to add controls dynamically into my ItemsControl. I am using RadHubTile control but I think this applies to any control. My XAML

<ItemsControl x:Name="itemsControl" ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <telerikPrimitives:RadUniformGrid x:Name="radUniformGrid" NumberOfColumns="3" NumberOfRows="3" />       
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

Adding new control works fine and it binds correctly. The problem occur when I navigated away from the page and returned back. I get this error

MS.Internal.WrappedException: Element is already the child of another element. --->     System.InvalidOperationException: Element is already the child of another element.
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.Collection_AddValue[T](PresentationFrameworkCollection`1     collection, CValue value)
   at MS.Internal.XcpImports.Collection_AddDependencyObject[T]    (PresentationFrameworkCollection`1 collection, DependencyObject value)    
 at System.Windows.PresentationFrameworkCollection`1.AddDependencyObject(DependencyObject value)
   at System.Windows.Controls.UIElementCollection.AddInternal(UIElement value)
   at System.Windows.PresentationFrameworkCollection`1.Add(T value)
   at System.Windows.Controls.ItemsControl.AddVisualChild(Int32 index, DependencyObject container, Boolean needPrepareContainer)
   at System.Windows.Controls.ItemsControl.AddContainers()
   at System.Windows.Controls.ItemsControl.RecreateVisualChildren(IntPtr unmanagedObj)
   --- End of inner exception stack trace ---

I suspect it's because the radHubTile elements have parents already. Perhaps I have to remove them from the visualtree or from ItemsControl when moving away from the page? I tried to do this via code behind OnBackKeyPress but I am not sure how exactly to achieve this. Or if that will fix the problem.

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    foreach (var item in itemsControl.Items)
    {
        UIElement uiElement =
            (UIElement)itemsControl.ItemContainerGenerator.ContainerFromItem(item);
        //this.itemsControl.Items.Remove(uiElement);      
    }            
}

EDIT

The above gives the following error when trying to remove the uiElement

{System.InvalidOperationException: Operation not supported on read-only collection.

Any suggestions? Thanks.


Solution

  • It looks like you're binding a collection of UI elements (RadHubTile) to your ItemsControl. Rather than doing this you should either add the tiles to your ItemsControl directly in XAML in the Items collection or bind a collection of data (non-UI) objects for your tiles to ItemsSource and then use an ItemTemplate to declare the RadHubTile control itself, which will then be generated for you as new instances whenever a new ItemsControl instance is created.