#452 – Data Binding Elements in a Collection to a Grid, Part V

We saw earlier that to bind Grid.Row and Grid.Column properties on child items in an ItemsControl,  we need to set up the binding on the ContentPresenter elements that contain the individual items.

We can do this by overriding the ItemsControl.PrepareContainerForItemOverride method.  This method is called for each item in the collection and receives both the containing element (a ContentPresenter in our case) and the contained item (a ChessPiece object in our example).  We bind the Grid.Row and Grid.Column properties on the ContentPresenter to the same properties on the contained item.

public class GridBasedItemsControl : ItemsControl
    {
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);

            ContentPresenter cp = element as ContentPresenter;

            if ((cp != null) && (item != null))
            {
                BindingOperations.SetBinding(cp, Grid.RowProperty, new Binding { Source = item, Path = new PropertyPath("Row")});
                BindingOperations.SetBinding(cp, Grid.ColumnProperty, new Binding { Source = item, Path = new PropertyPath("Column") });
            }

        }
    }

Everything now works as expected.

NOTE: Reader Bruno pointed out a much better way to do this, using the ItemContainerStyle property.

About these ads

About Sean
Software developer in the Twin Cities area, passionate about .NET technologies. Equally passionate about my own personal projects related to family history and preservation of family stories and photos.

6 Responses to #452 – Data Binding Elements in a Collection to a Grid, Part V

  1. Bruno says:

    I have the same effect if I change the item container style like this:

    What do you think about this aproach?

  2. Bruno says:

    I tried, but the xaml didn’t go, sorry…

    Trying again:

    • Bruno says:

      Not again, trying some replacements:

      [Window x:Class="WpfChess.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="MainWindow" Height="500" Width="500"]
      [Grid]
      [ItemsControl ItemsSource="{Binding ChessPieces}"]
      [ItemsControl.ItemsPanel]
      [ItemsPanelTemplate]
      [Grid ShowGridLines="True"]
      [Grid.RowDefinitions]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [RowDefinition Height="*"/]
      [/Grid.RowDefinitions]
      [Grid.ColumnDefinitions]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [ColumnDefinition Width="*"/]
      [/Grid.ColumnDefinitions]
      [/Grid]
      [/ItemsPanelTemplate]
      [/ItemsControl.ItemsPanel]
      [ItemsControl.ItemTemplate]
      [DataTemplate]
      [Label Content="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center" /]
      [/DataTemplate]
      [/ItemsControl.ItemTemplate]
      [ItemsControl.ItemContainerStyle]
      [Style]
      [Setter Property="Grid.Row" Value="{Binding Row}"/]
      [Setter Property="Grid.Column" Value="{Binding Column}"/]
      [/Style]
      [/ItemsControl.ItemContainerStyle]
      [/ItemsControl]
      [/Grid]
      [/Window]

      • Bruno says:

        Please replace [ and ] for the correct syntax, this was the only way I could paste the code.

      • Sean says:

        Thanks Bruno! Using ItemContainerStyle is a much better approach, much cleaner. I wrote a new post explaining this method (will be published on 21Dec11) and updated this post to point to it. Thanks again!

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 373 other followers

%d bloggers like this: