Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting Grid RowDefinitions/ColumnDefinitions properties in a style

Suppose that you have 2 or more grids that share the same structure (Rows/Columns count and properties are equal).

Is it possible to create a Style and set RowDefinitions/ColumnDefinitions?

I have tried that. But I get this exception when the application tries to parse the xaml:

Xamarin.Forms.Xaml.XamlParseException: Position 14:9. Property Value is null or is not IEnumerable

My Source code:

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <Style TargetType="Grid">
                <Setter Property="RowDefinitions">
                    <Setter.Value>
                        <RowDefinition />
                        <RowDefinition />
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>

Position 14:9 in the exception refers to the first <RowDefinition /> tag.

like image 385
Hadi Fooladi Talari Avatar asked Aug 14 '17 18:08

Hadi Fooladi Talari


2 Answers

Thanks to @j.f., I found the solution. I combined his idea with mine and here is the result:

The trick was adding the declaration into a separate resource and referencing it inside style.

<StackLayout>
    <StackLayout.Resources>
        <ResourceDictionary>
            <RowDefinitionCollection x:Key="MyRowDefinitionCollection">
                <RowDefinition />
                <RowDefinition />
            </RowDefinitionCollection>

            <Style TargetType="Grid">
                <Setter Property="RowDefinitions" Value="{StaticResource MyRowDefinitionCollection}" />
            </Style>
        </ResourceDictionary>
    </StackLayout.Resources>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #1) Row #1" />
        <Label Grid.Row="1" Text="(Grid #1) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #2) Row #1" />
        <Label Grid.Row="1" Text="(Grid #2) Row #2" />
    </Grid>

    <Grid>
        <Label Grid.Row="0" Text="(Grid #3) Row #1" />
        <Label Grid.Row="1" Text="(Grid #3) Row #2" />
    </Grid>
</StackLayout>
like image 151
Hadi Fooladi Talari Avatar answered Nov 19 '22 11:11

Hadi Fooladi Talari


You can't define RowDefinition and ColumnDefinition within a style, but you can create them as reusable resources. I think this is what you're looking for. Defining a ColumnDefinitionCollection and a RowDefinitionCollection like so allows you to reuse them with many grids to create a consistent look.

<ResourceDictionary>
    <ColumnDefinitionCollection
        x:Key="MyColumnDefinitionCollection">
        <ColumnDefinition
            Width="50" />
        <ColumnDefinition
            Width="100" />
        <ColumnDefinition
            Width="150" />
    </ColumnDefinitionCollection>
    <RowDefinitionCollection
        x:Key="MyRowDefinitionCollection">
        <RowDefinition
            Height="50" />
        <RowDefinition
            Height="50" />
        <RowDefinition
            Height="100" />
        <RowDefinition
            Height="100" />
    </RowDefinitionCollection>
</ResourceDictionary>
<Grid 
    ColumnDefinitions="{StaticResource MyColumnDefinitionCollection}"
    RowDefinitions="{StaticResource MyRowDefinitionCollection}">
</Grid>
like image 18
j.f. Avatar answered Nov 19 '22 09:11

j.f.