I've been struggling with this issue for too long. Something that is supposed to be very simple.. I'm making a Tic Tac Toe app in Xamarin.Forms. The board itself contains 3x3 buttons, each button is placed in its own Grid cell. I have 3 cells horizontally and 3 cells vertically.
The grid with these cells are placed in a Grid row from another Grid. The horizontal part of the board automatically expands, so that it takes up the entire width of the screen, as you can see from the picture. But I want the height of the buttons/grid rows to be the exact same, so that they create a perfect square. I can do that by hardcoding a value when creating the button using HeightRequest = someValue, but I want to bind it to the width of the button/gridColumn, so that it looks good no matter what device you are running on.
In this example I hardcoded the height of the Grid row. As you can see, it looks fine on the iPhone, but terrible on the iPad due to the larger display and higher amount of pixels. If only I could make the height the same as the width it would be perfect.
The grid is made in XAML:
<Grid x:Name="rootGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70" />
<RowDefinition Height="60" />
<RowDefinition Height="400"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="Tic Tac Toe" HorizontalOptions="Center" VerticalOptions="StartAndExpand" Padding="0,50,0,0" FontFamily="Arial" FontAttributes="Bold" FontSize="Large" TextColor="#FFFFFF" Grid.Row="0" Grid.Column="0"/>
<Grid Grid.Row="1" Margin="0,20,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label HorizontalTextAlignment="Center" Text="X: 0 points" Grid.Column="0" TextColor="#FFFFFF" IsVisible="True"></Label>
<Label HorizontalTextAlignment="Center" Text="O: 0 points" Grid.Column="1" TextColor="#FFFFFF" IsVisible="True"></Label>
</Grid>
<Grid Grid.Row="2" x:Name="theBoard">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="col1" Width="*" />
<ColumnDefinition x:Name="col2" Width="*" />
<ColumnDefinition x:Name="col3" Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<!--<RowDefinition BindingContext="{x:Reference Name=col1}" Height="{Binding Path=Width}"/>-->
</Grid.RowDefinitions>
</Grid>
</Grid>
And the buttons are added like this:
private void CreateFields()
{
// Iterate through the rows
for (int i = 0; i < fields.GetLength(1); i++)
{
// Iterate through the columns
for (int j = 0; j < fields.GetLength(0); j++)
{
Button field = new Button()
{
BackgroundColor = Color.WhiteSmoke,
};
// Adds the new button to the two dimensional array
fields[i, j] = field;
theBoard.Children.Add(field, j, i);
}
}
//Console.WriteLine("The current width of the button is: " + fields[0,0].Width);
//Console.WriteLine("The current height of the button is: " + fields[0,0].Height);
//Console.WriteLine("The current width of the column is: " + col1.Width);
// Console.WriteLine("The current height of the column is: " + row1.Height);
}
I really hope someone is able to help me. Its gotta be some simple detail I forgot. In WPF I was used to have something called "ActualWidth" but this doesn't seem to be the case here.
Grid
Layout if you want to which would fit based on the Area! – FreakyAli