views:

1541

answers:

3

I have a grid and I need to dynamically replace a control that resides in one of the cells. I don't know in terms of syntax to pinpoint the grid cell, as where do I put in the row and column number so I can delete whatever is in it.

+1  A: 

You could iterate the children of the grid checking their row and column values using the Grid.GetRow and Grid.GetColumn methods and replace the targeted content when the values match. Here's a sample tested in WPF, but should work in Silverlight:

    <Grid x:Name="SampleGrid">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Rectangle Fill="Red" Width="20" Height="20" Grid.Row="0" Grid.Column="0" />
    <Rectangle Fill="Orange" Width="20" Height="20" Grid.Row="0" Grid.Column="1" />
    <Rectangle Fill="Yellow" Width="20" Height="20" Grid.Row="0" Grid.Column="2" />
    <Rectangle Fill="Green" Width="20" Height="20" Grid.Row="1" Grid.Column="0" />
    <Rectangle Fill="Blue" Width="20" Height="20" Grid.Row="1" Grid.Column="1" />
    <Rectangle Fill="Indigo" Width="20" Height="20" Grid.Row="1" Grid.Column="2" />
    <Rectangle Fill="Violet" Width="20" Height="20" Grid.Row="2" Grid.Column="0" />
    <Rectangle Fill="Black" Width="20" Height="20" Grid.Row="2" Grid.Column="1" />
    <Rectangle Fill="Gray" Width="20" Height="20" Grid.Row="2" Grid.Column="2" />
    <Button Grid.Row="3" Grid.ColumnSpan="3" Margin="10" x:Name="Swap" Click="Swap_Click" Content="Swap"/>
</Grid>

In the event handler:

    private void Swap_Click(object sender, RoutedEventArgs e)
    {
        Ellipse newEllipse = new Ellipse() { Fill = new SolidColorBrush(Colors.PaleGoldenrod), Width = 20d, Height = 20d };
        for (int childIndex = 0; childIndex < this.SampleGrid.Children.Count; childIndex++)
        {
            UIElement child = this.SampleGrid.Children[childIndex];
            if (Grid.GetColumn(child) == 2 && Grid.GetRow(child) == 2)
            {
                this.SampleGrid.Children.Remove(child);
                Grid.SetRow(newEllipse, 2);
                Grid.SetColumn(newEllipse, 2);
                this.SampleGrid.Children.Add(newEllipse);
            }
        }

    }
Gordon Mackie JoanMiro
Should have added that if you have a large number or row/cols you might want to add a break statement to avoid iterating the remaining children once you have hit your target.
Gordon Mackie JoanMiro
+4  A: 

If you know the cell and row that the control lives in, you can use a LINQ statement to grab it.

Here's a LINQ statement that will get the first control that is in column 3, row 4.

var control = (from d in grid.Children
               where Grid.GetColumn(d as FrameworkElement) == 3 
                  && Grid.GetRow(d as FrameworkElement) == 4
               select d).FirstOrDefault();
Brad Tutterow
Nice - once again LINQ does away with the need for loops.
Gordon Mackie JoanMiro
A: 

You can remember de control that I put in the grid adding a private variable:

private Control controlCentral = null;

Next, asign to this variable the control that you add to the grid, so you can use Remove for remove the control of the grid.

The next code replace the control of row 0 column 1:

private void MostrarControlCentral(Control control)
    {
        if (control != null)
        {
            control.SetValue(Grid.RowProperty, 0);
            control.SetValue(Grid.ColumnProperty, 1);
        }

        this.LayoutRoot.Children.Remove(this.controlCentral);
        if (control != null)
        {
            this.LayoutRoot.Children.Add(control);
        }
        this.controlCentral=control;
    }
Juan Carlos