Rectangle in Xamarin forms does not honor the HeightRequest - xaml

I am trying to set the HeightRequest of a Rectangle to 10, but the height instead fills the entire height of the Grid. What am I doing wrong or is this a bug in Xamarin Forms. I am using Xamarin.Forms 5.0.0.2012.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<shapes:Rectangle Grid.Row="0" Grid.Column="0"
Fill="Green"
StrokeThickness="0"
WidthRequest="50"
HeightRequest="10"/>
<Label Grid.Row="0" Grid.Column="1"
Style="{StaticResource Subtitle1TextStyle}"
Text="Green area: ideally, your average lines would stay within your target range." />
<shapes:Rectangle Grid.Row="1" Grid.Column="0"
Fill="Black"
StrokeThickness="0"
WidthRequest="50"
HeightRequest="10"/>
<Label Grid.Row="1" Grid.Column="1"
Style="{StaticResource Subtitle1TextStyle}"
Text="Black line: The black line has a lot of text on this line. The Rectangle height keeps growing even though the height request has been set to 10." />
</Grid>

Because you are putting the Label and the black rectangle on the same Row (which have it Height set to Auto), it means it will take the maximum Height of the elements in that Row which in your case is the Label, thus the rectangle will get the same Height as the Label even that you have specified it HeightRequestto be 10.
To overcome this create another Row and span the Label over Row 2 and 3, also notice the new simplified syntax for ColumnDefinition and RowDefinition:
<Grid RowDefinitions="auto,auto,auto" ColumnDefinitions="auto,*">
<Rectangle Grid.Row="0" Grid.Column="0"
Fill="Green"
StrokeThickness="0"
WidthRequest="50"
HeightRequest="10"/>
<Label Grid.Row="0" Grid.Column="1"
Text="Green area: ideally, your average lines would stay within your target range."/>
<Rectangle Grid.Row="1" Grid.Column="0"
Fill="Black"
VerticalOptions="Fill"
StrokeThickness="0"
WidthRequest="50"
HeightRequest="10"/>
<Label Grid.Row="1" Grid.Column="1"
Grid.RowSpan="2"
TextColor="Black"
Text="Black line: The black line has a lot of text on this line. The Rectangle height keeps growing even though the height request has been set to 10."/>
</Grid>

Related

xamarin.forms XAML CODE TO MINIMIZE DISTANCE BETWEEN Label and button

I am developing a xamarin.forms app and here as shown in the images I am getting wide vertical spacing between label field and buttons, so I need to decrease them and align them in proper order, here is the XAML code so please suggest me what changes do I need to make?
<ScrollView>
<StackLayout Padding="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".3*"></ColumnDefinition>
<ColumnDefinition Width=".5*"></ColumnDefinition>
<ColumnDefinition Width=".2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
>
<Label Text="Name" Grid.Column="0" Grid.Row="4" Style="
{DynamicResource SizedLabel}" TextColor="Black"
VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand"
HorizontalTextAlignment="Start"/>
<Entry x:Name="name" Grid.Column="1" Grid.Row="4"
Placeholder="" WidthRequest="100" FontAttributes="None" FontSize="Small"
BackgroundColor="Transparent" VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand"></Entry>
<Label x:Name="qty_lbl" Text=" Quantity"
Grid.Column="0" Grid.Row="5" Style="{DynamicResource SizedLabel}"
TextColor="Black" VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand" HorizontalTextAlignment="Start"/>
**<Entry x:Name="quantity" Grid.Column="1" Grid.Row="6"
Keyboard="Numeric" Placeholder="" WidthRequest="100"
FontAttributes="None" FontSize="Small" BackgroundColor="Transparent"
VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
</Entry>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".1*"></ColumnDefinition>
<ColumnDefinition Width=".1*"></ColumnDefinition>
<ColumnDefinition Width=".1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button x:Name="save_btn" BackgroundColor="DodgerBlue"
Grid.Column="0" Grid.Row="1" TextColor="White" Text="Next/Save"
Clicked="OnSave" BorderColor="Black"/>
<Button x:Name="cancel_btn" BackgroundColor="DodgerBlue"
Grid.Column="1" Grid.Row="1" TextColor="White" Text="Cancel"
Clicked="OnCancel" BorderColor="Black"/>
<Button x:Name="close_btn" BackgroundColor="DodgerBlue"
Grid.Column="2" Grid.Row="1" TextColor="White" Text="Close"
Clicked="OnClose" BorderColor="Black"/>
</Grid>**
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackLayout Orientation="Horizontal" HeightRequest="40"
HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="0"
BackgroundColor="LightGray">
<Label x:Name="count_label" Text="" Style="
{DynamicResource SizedLabel}" TextColor="Gray"
HorizontalTextAlignment="Start" VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand"></Label>
</StackLayout>
</Grid>
</StackLayout>
</ScrollView>
</StackLayout>
To make the buttons move up what changes do I need to make?
thanks
The problem lays in the use you make of the Grid.Row attached property. In the first grid, you define 2 rows but, then, you assign to some of its children controls the property Grid.Row to 4, 5 and 6. This implicitly force the creation of additional rows, and you end up with a grid with 7 rows (because of course rows are 0 based).
When the rows aren't given an explicit height, they are given "*", which means "equally proportional", that is, all of the same size. That's alone create a lot of extra space.
Also, in the second Grid, the one with the buttons, you define it with only one row, but assign Grid.Row = "1" to all the three buttons, this way forcing the creation of a second row. Again, because you don't specify an height, the newly created row has the same size of the row containing the buttons.
To fix all this you have to:
Assign Grid.Row = "0" to the first Label and the first Entry.
Assign Grid.Row="1" to the second Label and the second Entry.
Assign Grid.Row="0" to all the three buttons.
If you instead want the labels to appear over the relative entry, then assign Grid.Row = "0" to the first Label, Grid.Row = "1" to the first Entry, Grid.Row = "2" to the second Label and Grid.Row = "3" to the second Entry.
Also, for clarity, define four Rows in the Grid, with Height="Auto" or Height="*".
To make your code more concise, please note:
0 is the default for both Grid.Row and Grid.Column, so you can get rid of such assignments;
You don't have to define a Grid.RowDefinitions property if your Grid has only one row. The same, you don't have to define a Grid.ColumnDefinitions property if your Grid has only one column.
There is no use in using decimal notation when expressing height or width with "*" values. Star values indicate a proportion between rows (or columns), so for example if a row is "2*" and a second row is "*", the first row will be twice as tall than the second. The sum of the stars assigned to the rows (or the columns) can be any number, because it has no particular meaning, what is important is only the relative proportions between rows (or columns). To clarify even more, in the example made before, you could have assigned "100*" to the first row and "50* to the second: the result would have been the same.

Xamarin forms vertically center text over image

I'm learning Xamarin and I want to display an image as background with some texto over this image...
Just that, I manage to acomplish, but the text is displayed at the top left corner of the image.
I'd like the text to be placed at the vertical center of the image, but stick to the left side of it.
My code so far XAML:
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="20*" ></RowDefinition>
<RowDefinition Height="65*"></RowDefinition>
<RowDefinition Height="15*"></RowDefinition>
</Grid.RowDefinitions>
<RelativeLayout Grid.Row="0">
<Image Source="login.png" Aspect="Fill" />
<Label Text="Bem vindo" TextColor="White" FontSize="22"></Label>
</RelativeLayout>
<Label Grid.Row="1" Text="linha 2" BackgroundColor="Coral"></Label>
<Button Grid.Row="2" Text="linha 3" BackgroundColor="DarkRed"></Button>
</Grid>
I've tried verticalOptions and such, but with no effect.
One thing that kind of worked is settin a Maring property to the label, but that way, the label would be centered only to the device I'm testing on. Other devices, smaller or greater, the label could (and probably would) be placed at the wrong place.
Any help?
You don't need a RelativeLayout inside the Grid. The Grid itself already is able to handle views overlay besides let your code clearer.
It may works:
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="20*"></RowDefinition>
<RowDefinition Height="65*"></RowDefinition>
<RowDefinition Height="15*"></RowDefinition>
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0"
Source="login.png"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Aspect="Fill" />
<Label Grid.Row="0" Grid.Column="0"
Text="Bem vindo"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center"
TextColor="White"
FontSize="22"/>
<Label Grid.Row="1"
Text="linha 2"
BackgroundColor="Coral"/>
<Button Grid.Row="2"
Text="linha 3"
BackgroundColor="DarkRed"/>
</Grid>

How to use full width of Phone in xaml?

I have 3 controls in a Grid.Row but how can I make them use the full width of the page?
This is my xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="140" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Grid.Row="1"
Source="/Assets/image1.png"
Height="25"
Width="25" />
<TextBox Grid.Column="1"
Margin="10,0,0,0"
Text="{Binding InputText, Mode=TwoWay}"
BorderBrush="Black"
BorderThickness="2"
VerticalAlignment="Center">
</TextBox>
<Button Grid.Column="2"
BorderThickness="2"
HorizontalAlignment="Right"
Command="{Binding AddTextCommand}"
Margin="10,0,0,0">
<TextBlock x:Uid="ButtonText" />
</Button>
</Grid>
This is now the result:
As you can see it is aligned left, how can I make it use the full width?
You're code only shows 3 controls (Image, TextBox, Button), while your screenshot gives 4 controls. I suppose the full width control on top is missing, but that's no problem to answer the question.
If we break down your XAML, you have:
First column width Auto, filled with an image.
Second column width 140, filled with a TextBox
Third column width * (or the rest of the space), filled with a Button
On the button you have placed HorizontalAlignment="Right" (default is Left), in which you're saying: only use the space necessary and put the control on the right side. If you want to use the full width available, you have to use HorizontalAlignment="Stretch".
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="140" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="/Assets/image1.png"
Height="25"
Width="25" />
<TextBox Grid.Column="1"
Margin="10,0,0,0"
Text="{Binding InputText, Mode=TwoWay}"
BorderBrush="Black"
BorderThickness="2"
VerticalAlignment="Center">
</TextBox>
<Button Grid.Column="2" x:Uid="ButtonText"
BorderThickness="2"
HorizontalAlignment="Stretch"
Command="{Binding AddTextCommand}"
Margin="10,0,0,0" />
</Grid>
Note that I have also removed the TextBlock from the Button and move the x:Uid tag to the button. Simply use ButtonText.Content in your resources to have your button localized, there's no need to place a TextBlock in there.

Dynamically expanding Grid also expands fixed height Rows and Columns

I have a dynamically expanding Grid inside another Grid which is separated onto 4 rows and 4 columns.
My main content grid spans 4 rows and 2 columns and dynamically loads different Views, and sometimes expands in height. My problem is, the other rows are also expanded although they have a fixed height, which makes the layout appear weird.
I want to keep all the rows' heights to 36, but just expand the lowest row so all content of my grid is shown.
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="110" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="36" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
FontSize="14"
Content="X">
</Button>
<Grid x:Name="MainPaymentContentRoot"
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="20,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollMode="Auto">
</Grid>
<TextBlock Text="MyField" Grid.Row="0" Grid.Column="3" Margin="10,0,0,0" VerticalAlignment="Center" />
<Button Grid.Row="1" Grid.Column="3" Margin="10,0,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Right"
Content="AnotherButton">
</Button>
</Grid>
This is for a Win 8 Development.
Currently, your RowDefinition is set to Auto. This means that the row will calculate the content size, and adjust it's height accordingly.
You need to change it to Height="*".
<RowDefinition Height="*" />
This will force the RowDefinition to expand to the height of the parent. In other words, it will take up all available space.

Disable opacity on Textblock when grid's opacity is set for WP8

I've posted a similar question in the past but never quite resolved it and so here I am again.
In my layout grid, I have an image which takes the full area but I also display another grid which is vertically aligned to the bottom, has its background color set and its opacity set to .5.
This part works fine.
Now, I want to display another grid within that grid which will contain another image (a logo) and a TextBlock which contains a description.
My problem is that both the image and textblock are being dimmed. While I have no problem with the logo being dimmed, I do want to keep my description fully opaque but can't seem to be able to do this.
Is there a way to achieve this? Note I'm trying to build a custom tile for WP8.
Here is the code:
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Stretch="UniformToFill" Source="/Assets/0.jpeg" ></Image>
<Grid Background="#0F558E" Opacity="0.5" Visibility="Visible" Height="100" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="/Assets/Tiles/FlipCycleTileSmall.png" Width="100" Height="100" Grid.Column="0" Opacity="1" ></Image>
<TextBlock Foreground="White" FontSize="30" Text="This is a simple description of the article" TextWrapping="Wrap" Margin="10,0,30,0" Grid.Column="1" Opacity="1" />
</Grid>
</Grid>
Thanks.
As you found out, everything that is a child of that grid is going to have a 0.5 opacity, and any opacity settings on the children are going to be relative to that.
Could you just overlay a third grid on top of the second that has the same sizing and contains your image and text? I don't have anything in front of me to test this at the moment, but something like:
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Stretch="UniformToFill" Source="/Assets/0.jpeg" ></Image>
<Grid Background="#0F558E" Opacity="0.5" Visibility="Visible" Height="100" VerticalAlignment="Bottom">
</Grid>
<Grid Visibility="Visible" Height="100" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="/Assets/Tiles/FlipCycleTileSmall.png" Width="100" Height="100" Grid.Column="0" Opacity="1" ></Image>
<TextBlock Foreground="White" FontSize="30" Text="This is a simple description of the article" TextWrapping="Wrap" Margin="10,0,30,0" Grid.Column="1" Opacity="1" />
</Grid>
</Grid>