Search code examples
c#wpfxamlmvvm

"Specified visual is already a child of another visual or root of a CompositionTarget" C# Wpf


I have a blank domino piece and I want to fill it with dots with this function:

private void Arrange(Grid grid, byte dots)
        {

            Ellipse e = new Ellipse
            {
                Fill = new SolidColorBrush(Colors.Black)
            };

            Border b = new Border
            {
                Background = new SolidColorBrush(Colors.Black),
                Margin = new Thickness(0, 5, 0, 5),
                CornerRadius = new CornerRadius(2.5)
            };

            //BoneView.Layout.Children.Add(b);
            Grid.SetColumn(b, 1);

            if (dots == 0)
                return;

            if (dots == 1)
            {
                grid.Children.Add(e);
                Grid.SetColumn(e, 1);
                Grid.SetRow(e, 1);
                return;
            }

            if (dots == 2)
            {
                List<Ellipse> ellipses = new List<Ellipse>();
                for (int i = 0; i < dots; i++)
                {
                    ellipses.Add(e);
                    grid.Children.Add(ellipses[i]);
                }


                Grid.SetColumn(ellipses[1], 2);
                Grid.SetRow(ellipses[1], 2);
                return;
            }

            if (dots == 3)
            {
                List<Ellipse> ellipses = new List<Ellipse>();
                for (int i = 0; i < dots; i++)
                {
                    ellipses.Add(e);
                    grid.Children.Add(ellipses[i]);
                }


                Grid.SetColumn(ellipses[1], 2);
                Grid.SetRow(ellipses[1], 2);

                Grid.SetColumn(ellipses[2], 1);
                Grid.SetRow(ellipses[2], 1);
                return;
            }

            if (dots == 4)
            {
                List<Ellipse> ellipses = new List<Ellipse>();
                for (int i = 0; i < dots; i++)
                {
                    ellipses.Add(e);
                    grid.Children.Add(ellipses[i]);
                }


                Grid.SetColumn(ellipses[1], 2);
                Grid.SetRow(ellipses[1], 2);

                Grid.SetColumn(ellipses[2], 2);
                Grid.SetRow(ellipses[2], 0);

                Grid.SetColumn(ellipses[3], 0);
                Grid.SetRow(ellipses[3], 2);
                return;
            }

            if (dots == 5)
            {
                List<Ellipse> ellipses = new List<Ellipse>();
                for (int i = 0; i < dots; i++)
                {
                    ellipses.Add(e);
                    grid.Children.Add(ellipses[i]);
                }


                Grid.SetColumn(ellipses[1], 2);
                Grid.SetRow(ellipses[1], 2);

                Grid.SetColumn(ellipses[2], 2);
                Grid.SetRow(ellipses[2], 0);

                Grid.SetColumn(ellipses[3], 0);
                Grid.SetRow(ellipses[3], 2);

                Grid.SetColumn(ellipses[4], 1);
                Grid.SetRow(ellipses[4], 1);
                return;
            }

            if (dots == 6)
            {
                List<Ellipse> ellipses = new List<Ellipse>();
                for (int i = 0; i < dots; i++)
                {
                    ellipses.Add(e);
                    grid.Children.Add(ellipses[i]);
                }

                Grid.SetColumn(ellipses[1], 2);
                Grid.SetRow(ellipses[1], 2);

                Grid.SetColumn(ellipses[2], 2);
                Grid.SetRow(ellipses[2], 0);

                Grid.SetColumn(ellipses[3], 0);
                Grid.SetRow(ellipses[3], 2);

                Grid.SetColumn(ellipses[4], 1);
                Grid.SetRow(ellipses[4], 0);

                Grid.SetColumn(ellipses[5], 1);
                Grid.SetRow(ellipses[5], 2);
                return;
            }

At grid.Children.Add(e) it throws "Specified visual is already a child of another visual or root of a CompositionTarget" exception.

From what I understand this happens because Ellipse e is already added to the grid.

How do I fix this?

Here is the domino design:

<Border Background="AntiqueWhite"
            CornerRadius="7"
            >

        <Grid Name="Layout">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="5"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Grid Grid.Column="0" x:Name="Left">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

            </Grid>

            <Grid Grid.Column="2" x:Name="Right">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

            </Grid>

        </Grid>

    </Border>

Solution

  • It's because you instantiate the Ellipse at the top of your function, this code Ellipse e = new Ellipse..., and then when a domino has multiple dots you add the same instantiated e for each dot you are adding. You need to instantiate the Ellipse each time you want to add a dot.

    The simple solution would be to instantiate the Ellipse in the for...each loops where you are adding the dots, as I've done in the below.

    private void Arrange(Grid grid, byte dots)
    {
        // let's create a single brush for all the black dots
        // so we don't have to create a brush for each dot
        var blackBrush = new SolidColorBrush(Colors.Black);
    
        Border b = new Border
        {
            Background = new SolidColorBrush(Colors.Black),
            Margin = new Thickness(0, 5, 0, 5),
            CornerRadius = new CornerRadius(2.5)
        };
    
        //BoneView.Layout.Children.Add(b);
        Grid.SetColumn(b, 1);
    
        if (dots == 0)
            return;
    
        if (dots == 1)
        {
            // create ellipse to add
            Ellipse e = new Ellipse
            {
                Fill = blackBrush 
            };
            grid.Children.Add(e);
            Grid.SetColumn(e, 1);
            Grid.SetRow(e, 1);
            return;
        }
    
        if (dots == 2)
        {
            List<Ellipse> ellipses = new List<Ellipse>();
            for (int i = 0; i < dots; i++)
            {
                // create each ellipse to add
                Ellipse e = new Ellipse
                {
                    Fill = blackBrush 
                };
                ellipses.Add(e);
                grid.Children.Add(ellipses[i]);
            }
            Grid.SetColumn(ellipses[1], 2);
            Grid.SetRow(ellipses[1], 2);
            return;
        }
    
        if (dots == 3)
        {
            List<Ellipse> ellipses = new List<Ellipse>();
            for (int i = 0; i < dots; i++)
            {
                // create each ellipse to add
                Ellipse e = new Ellipse
                {
                    Fill = blackBrush 
                };
                ellipses.Add(e);
                grid.Children.Add(ellipses[i]);
            }
            Grid.SetColumn(ellipses[1], 2);
            Grid.SetRow(ellipses[1], 2);
            Grid.SetColumn(ellipses[2], 1);
            Grid.SetRow(ellipses[2], 1);
            return;
        }
    
        if (dots == 4)
        {
            List<Ellipse> ellipses = new List<Ellipse>();
            for (int i = 0; i < dots; i++)
            {
                // create each ellipse to add
                Ellipse e = new Ellipse
                {
                    Fill = blackBrush 
                };
                ellipses.Add(e);
                grid.Children.Add(ellipses[i]);
            }
            Grid.SetColumn(ellipses[1], 2);
            Grid.SetRow(ellipses[1], 2);
            Grid.SetColumn(ellipses[2], 2);
            Grid.SetRow(ellipses[2], 0);
            Grid.SetColumn(ellipses[3], 0);
            Grid.SetRow(ellipses[3], 2);
            return;
        }
    
        if (dots == 5)
        {
            List<Ellipse> ellipses = new List<Ellipse>();
            for (int i = 0; i < dots; i++)
            {
                // create each ellipse to add
                Ellipse e = new Ellipse
                {
                    Fill = blackBrush 
                };
                ellipses.Add(e);
                grid.Children.Add(ellipses[i]);
            }
            Grid.SetColumn(ellipses[1], 2);
            Grid.SetRow(ellipses[1], 2);
            Grid.SetColumn(ellipses[2], 2);
            Grid.SetRow(ellipses[2], 0);
            Grid.SetColumn(ellipses[3], 0);
            Grid.SetRow(ellipses[3], 2);
            Grid.SetColumn(ellipses[4], 1);
            Grid.SetRow(ellipses[4], 1);
            return;
        }
    
        if (dots == 6)
        {
            List<Ellipse> ellipses = new List<Ellipse>();
            for (int i = 0; i < dots; i++)
            {
                // create each ellipse to add
                Ellipse e = new Ellipse
                {
                    Fill = blackBrush 
                };
                ellipses.Add(e);
                grid.Children.Add(ellipses[i]);
            }
            Grid.SetColumn(ellipses[1], 2);
            Grid.SetRow(ellipses[1], 2);
            Grid.SetColumn(ellipses[2], 2);
            Grid.SetRow(ellipses[2], 0);
            Grid.SetColumn(ellipses[3], 0);
            Grid.SetRow(ellipses[3], 2);
            Grid.SetColumn(ellipses[4], 1);
            Grid.SetRow(ellipses[4], 0);
            Grid.SetColumn(ellipses[5], 1);
            Grid.SetRow(ellipses[5], 2);
            return;
        }
    }