Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms bind Height of Grid to Width of Button

I try to build the following UI Element with Xamarin.Forms. I was able to build this with UWP by binding the Height property of the TopGrid to the ActualWidth property of Button1. However this is not working in Xamarin.Forms, because there is no ActualWidth property. I already tried binding the Height of TopGrid to WidthRequest, but without success.

enter image description here

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid x:Name="TopGrid" Grid.Row="0" BindingContext="{x:Reference Name=Button1}"  Height="{Binding Path=WidthRequest}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button x:Name="Button1" Grid.Column="0" Text="1" />
        <Button x:Name="Button2" Grid.Column="1" Text="2" />
        <Button x:Name="Button3" Grid.Column="2" Text="3" />
        <Button x:Name="Button4" Grid.Column="3" Text="4" />
    </Grid>
</Grid>

Does anybody have experience with Xamarin.Forms and can help me with this problem?

like image 526
nor0x Avatar asked Dec 04 '22 23:12

nor0x


1 Answers

First thing first: Xaml names are case-sensitive, so instead of

BindingContext="{x:Reference Name=button1}"

this should be

BindingContext="{x:Reference Name=Button1}"

Beside this, your Xaml was almost ok. Let's look at

Height="{Binding Path=WidthRequest}"

You're trying to bind to the view's height, but the HeightProperty is a read-only BindableProperty, so you can't set it. If you look at the API, there's no public setter for the Height property either. So, instead of binding to the Height, you should bind to the HeightRequest.

HeightRequest="{Binding Path=WidthRequest}"

That's the way of saying that you'd like the Grid to be of that height, and the layout system will do its best to make you happy (but that's a best effort only).

I think you get this by now. The button WidthRequest is the request made by the user, and in this case, it's not set and it's value is left to the default. Instead, you want to use the button's actual Width as source property of your binding. Let's do it:

HeightRequest="{Binding Width}"

and this gives the expected result:

actual result

Here's the full corrected Xaml snippet:

<Grid>
  <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <Grid x:Name="TopGrid" Grid.Row="0" BindingContext="{x:Reference Name=Button1}"  HeightRequest="{Binding Width}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button x:Name="Button1" Grid.Column="0" Text="1" BackgroundColor="Pink"/>
    <Button x:Name="Button2" Grid.Column="1" Text="2" BackgroundColor="Pink"/>
    <Button x:Name="Button3" Grid.Column="2" Text="3" BackgroundColor="Pink"/>
    <Button x:Name="Button4" Grid.Column="3" Text="4" BackgroundColor="Pink"/>
  </Grid>
</Grid>
like image 58
Stephane Delcroix Avatar answered Jan 22 '23 00:01

Stephane Delcroix