VariableSizedWrapGrid inside an ItemsControl with ColumnSpan and RowSpan

Recently, I used an ItemsControl control to my XAML page and wanted to use a VariableSizedWrapGrid as the container. The idea was to show the first item in my collection as large (2×2 in the grid) and the rest of the items to be normally sized.

The effect I wanted was essentially this:



So what’s the problem?

The problem is that binding ColumnSpan and RowSpan on a DataTemplate of an ItemsControl simply does not work – the issue is that when the visual tree is built, ItemsControl builds a wrapper for each DataTemplate and since VariableSizedWrapGrid needs the elements specifying ColumnSpan and RowSpan to be direct descendants, it just doesn’t work.

So what’s the solution?

We will create a derived class from ItemsControl (that is built to specifically work with VariableSizedWrapGrid). First, we add dependency properties for the converters that will be used to determine the row/col span:

public static readonly DependencyProperty ColumnSpanConverterProperty =
        DependencyProperty.Register("ColumnSpanConverter", typeof(IValueConverter), typeof(VariableSizedWrapGridItemsControl), new PropertyMetadata(null));
public static readonly DependencyProperty RowSpanConverterProperty =
        DependencyProperty.Register("RowSpanConverter", typeof(IValueConverter), typeof(VariableSizedWrapGridItemsControl), new PropertyMetadata(null));

public VariableSizedWrapGridItemsControl()


public IValueConverter ColumnSpanConverter
    get { return (IValueConverter)GetValue(ColumnSpanConverterProperty); }
    set { SetValue(ColumnSpanConverterProperty, value); }

public IValueConverter RowSpanConverter
    get { return (IValueConverter)GetValue(RowSpanConverterProperty); }
    set { SetValue(RowSpanConverterProperty, value); }

.csharpcode, .csharpcode pre
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
background-color: #f4f4f4;
width: 100%;
margin: 0em;
.csharpcode .lnum { color: #606060; }

Then, PrepareContainerForItemOverride() needs to be overridden so that we can use the converters – the item will be passed into the converter and it will decide what the size is:

protected override void PrepareContainerForItemOverride(Windows.UI.Xaml.DependencyObject element, object item)
        int? columnSpan = GetIntFromConverter(ColumnSpanConverter, item);
        if (columnSpan.HasValue)
            VariableSizedWrapGrid.SetColumnSpan((UIElement)element, columnSpan.Value);

        int? rowSpan = GetIntFromConverter(RowSpanConverter, item);
        if (rowSpan.HasValue)
            VariableSizedWrapGrid.SetRowSpan((UIElement)element, rowSpan.Value);

    base.PrepareContainerForItemOverride(element, item);

For our converter, we simply check if the element is the first one in the list and we return 2 in that case:

public object Convert(object value, Type targetType, object parameter, string language)
int result = 1;
if (value == Collection.OfType<object>().FirstOrDefault())
result = 2;

return result;


Note that Collection is an IEnumerable dependency property that can be bound to.

Finally, here’s the XAML used. First, defining the converter as a resource:

<local:FirstItemBigConverterBig x:Key="bigConverter" Collection="{Binding Items}">

And the actual ItemsControl derived class with the converter set in the correct properties:

<local:VariableSizedWrapGridItemsControl x:Name="itemsControl" ItemsSource="{Binding Items}" RowSpanConverter="{StaticResource bigConverter}"  ColumnSpanConverter="{StaticResource bigConverter}">
<VariableSizedWrapGrid Orientation="Vertical" ItemWidth="160" ItemHeight="160"/>
<Border BorderThickness="4" BorderBrush="Pink" Margin="0,0,12,12">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding}" FontSize="50"/>


And that’s it! You can download the full source code from here.

This entry was posted in Dev, Windows8. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s