0

I'm trying to fill a Grid using different X and Y values for Grid.Row and Grid.Column using an ItemsControl, I copied it from a WPF project of mine and can't get it to work in Silverlight (Windows Phone).

Here is a simplified version of it:

ViewModel which the DataContext is set to:

public class ViewModel
{
    public ObservableCollection<GridItem> Data { get; set; }

    public ViewModel()
    {
        Data = new ObservableCollection<GridItem>();
        FillData();
    }

    // fill Data property with some random color GridItems
    private void FillData()
    {
        string[] colors = { "Red", "Green", "Yellow", "Blue" };
        Random r = new Random();

        for (int i = 0; i < 10; i++)
        {
            Data.Add(new GridItem(i, i, colors[r.Next(colors.Length)]));
        }
    }
}

public class GridItem
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Color { get; set; }

    public GridItem(int x, int y, string color)
    {
        X = x;
        Y = y;
        Color = color;
    }
}

The XAML:

<Grid x:Name="LayoutRoot" Background="Transparent">

    <ItemsControl ItemsSource="{Binding Data}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>                    
            <Grid Background="Orange">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse 
                    Grid.Row="{Binding Y}" 
                    Grid.Column="{Binding X}"
                    Fill="{Binding Color}"
                    Stroke="White" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

This is the result (it placed all ellipses on top of eachother):

Result

While it should have done this:

intention

Does anyone know why this doesn't work?

Jesse
  • 1,332
  • 2
  • 14
  • 25

2 Answers2

0

Try setting the binding for the Grid.Row and Grid.Column within the ContentPresenter rather than as part of the DataTemplate that defines the Ellipse:

    <ItemsControl.Resources>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Row" Value="{Binding Y}"/>
            <Setter Property="Grid.Column" Value="{Binding X}"/>
        </Style>
    </ItemsControl.Resources>
    <ItemsControl.ItemTemplate> 
        <DataTemplate> 
            <Ellipse  
                Fill="{Binding Color}" 
                Stroke="White" /> 
        </DataTemplate> 
    </ItemsControl.ItemTemplate> 
0

It's because the DataTemplate wraps its content in a ContentPresenter. The Grid.Row and Grid.Column properties only apply to direct descendants so in this case they are not relevant because they are two levels deep in the control hierarchy.

The ContentPresenter is added dynamically at run time when the DataTemplate renders. To make this work you'd need to hook into the dynamic generation of the items and set the Row and Column attached properties on the containing item.

There is a blog post showing one way of getting this working at: http://www.scottlogic.co.uk/blog/colin/2010/11/using-a-grid-as-the-panel-for-an-itemscontrol/

spoida
  • 2,655
  • 1
  • 23
  • 14