14

I'm trying to create a table with a variable number of rows and columns. I'm doing this with an ItemsControl which has a Grid as its ItemsPanel. And I know I can set Grid.Row and Grid.Column of each item through its ItemContainerStyle. But I don't know how to change the number of rows and columns and their sizes when I can't access the Grid by its name.


Question:

How can you modify RowDefinitions or ColumnDefinitions of a Grid in run-time without any code-behind using Binding?


This is the XAML code:

<ItemsControl Name="myItemsControl" ItemsSource="{Binding Cells}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Name="myGrid">

                <Grid.RowDefinitions>
                    <!-- unknown number of rows are added here in run-time -->
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <!-- known number of columns are added here in run-time -->
                </Grid.ColumnDefinitions>

            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style.../>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

I tried to add some RowDefinition in code behind but I couldn't find a way to gain access to myGrid by its name (or any other way) since it is inside an ItemsPanelTemplate.

I'm wondering if is there any way to programmatically add or modify RowDefinitions in run-time?

Bizhan
  • 16,157
  • 9
  • 63
  • 101

2 Answers2

31

You can use attached properties for a Grid that modify the RowDefinitions and ColumnDefinitions when those properties are set or changed.

It will allow you to write your Grid like this:

<Grid local:GridHelpers.RowCount="{Binding MaxGridRow}"
      local:GridHelpers.ColumnCount="3" />

Then just expose a property from your ViewModel which returns the largest row number in the Cells collection.

You can find a detailed implementation of those properties on my blog.

H.B.
  • 166,899
  • 29
  • 327
  • 400
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Thanks a lot. I feel relieved:) and by the way there was a tiny mistake in the last two methods. I changed them to : GetStarColumns(grid).Split(','); – Bizhan Jan 25 '12 at 22:21
  • @Bizz Thank you :) The first time I copied the code to wordpress it got rid of all special characters and I must have replaced the single quotes with double quotes by mistake. The extra `.ToString()` was there because the star columns/rows used to be an integer before I needed multiple star columns one day and decided to update it to a string – Rachel Jan 26 '12 at 03:47
  • How defined local in xaml? – arun d Apr 26 '17 at 04:06
  • @arund Usually something like `xmlns:local="clr-namespace:MyProjectNamespace"` in the `` tag. It tells WPF to use the term "local" as a shortcut to point to the XML NameSpace `MyProjectNamespace` – Rachel Apr 26 '17 at 13:55
  • 1
    Thanks for update @Rachel ..i have used UniformGrid instead of Grid and binded rows. [link]http://stackoverflow.com/questions/43627127/bind-dynamically-number-of-rowdefinition-to-a-grid-in-an-itemspaneltemplate?noredirect=1#comment74311216_43627127 – arun d Apr 26 '17 at 14:23
9

If you had access to the grid from code-behind you could do this:

var rowDefinition = new RowDefinition();
rowDefinition.Height = GridLength.Auto;
grid.RowDefinitions.Add(rowDefinition);
Bizhan
  • 16,157
  • 9
  • 63
  • 101
Y.Yanavichus
  • 2,387
  • 1
  • 21
  • 34
  • This won't help. I can't access `myGrid` by its name from within code. – Bizhan Jan 25 '12 at 21:06
  • 1
    You can't access *whatever it is* when it is the ItemPanelTemplate of an ItemsControl. @WtFudgE you are probably doing something else than that. – Xavier Huppé Mar 20 '14 at 18:46