Both Label in Grid (same column, diff row) move when text changed. Why? - xaml

Video showing the simulator: https://youtu.be/3ajany0iaCw
The codes:
<Grid HorizontalOptions="Center" VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Switch Grid.Column="0"
HorizontalOptions="Center"
IsToggled="{Binding SwitchToggled}"/>
<Label Grid.Column="1"
HorizontalOptions="Center"
Text="{Binding SwitchToggled,
Converter={StaticResource Key=boolToStrConv}}"/>
<Switch Grid.Column="0" Grid.Row="1"
HorizontalOptions="Center"
x:Name="switch2"/>
<Label Grid.Column="1" Grid.Row="1"
HorizontalOptions="Center"
Text="{Binding Source={x:Reference switch2},
Path=IsToggled,
Converter={StaticResource Key=boolToStrConv}}"/>
</Grid>
My expectation is that no matter how the Label's text length is changed, it would both be centered - considering that both of them has a HorizontalOptions Center.
Why did this happened and how do I fix this?

You need to look at the container that is grid is within and the fact that you are centering (floating) your grid within that container.
Assign a background color to your grid and a different one to its container and you will see that its size depends upon what it is contains since you are * (star) its size and the grid itself is "floating" in the center of its container, change the contents of the grid, the size of the grid changes:
<Grid VerticalOptions="Center" HorizontalOptions="Center" BackgroundColor="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Switch Grid.Column="0" HorizontalOptions="Center" BackgroundColor="Red" x:Name="switch1" />
<Label Grid.Column="1" HorizontalOptions="Center" BackgroundColor="Red" Text="False" x:Name="label1" />
<Switch Grid.Column="0" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" x:Name="switch2" />
<Label Grid.Column="1" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" Text="False" x:Name="label2" />
</Grid>
Lock the grid to fill its parent's width (via StartAndExpand in my example) and changing your label's text content will not cause your toggle's start position to move...
<Grid VerticalOptions="StartAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Switch Grid.Column="0" HorizontalOptions="Center" BackgroundColor="Red" x:Name="switch1" />
<Label Grid.Column="1" HorizontalOptions="Center" BackgroundColor="Red" Text="False" x:Name="label1" />
<Switch Grid.Column="0" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" x:Name="switch2" />
<Label Grid.Column="1" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" Text="False" x:Name="label2" />
</Grid>

Related

Replace a FlexLayout with a StackLayout

I have a Grid with two rows in Auto within a CollectionView. In one I have a FlexLayout, in the other a Label. For some strange problem, with these two controls the Label is not displayed and the only way I have found so far is to replace the FlexLayout with a StackLayout.
<DataTemplate>
<yummy:PancakeView CornerRadius="15">
<yummy:PancakeView.Shadow>
<yummy:DropShadow Color="LightBlue" Offset="10,10"/>
</yummy:PancakeView.Shadow>
<Grid BackgroundColor="{DynamicResource SfondoElemDiario}" RowSpacing="0.2">
<Grid.RowDefinitions>
<RowDefinition Height="27"/>
<RowDefinition Height="27"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Margin="4,4,4,7" Source="{Binding Umore}" VerticalOptions="Center"/>
<Label Grid.Row="0" FontFamily="FontM" Grid.Column="1" Text="{Binding GiornoTrascritto}" FontSize="16" TextColor="{DynamicResource TextColor}" Opacity="0.6" VerticalOptions="Center" />
<Label Grid.Row="1" FontFamily="FontM" Grid.Column="1" Text="{Binding Orario}" FontSize="16" TextColor="{DynamicResource TextColor}" Opacity="0.6" VerticalOptions="Center"/>
<ProgressBar Grid.Row="1" Grid.Column="0" ProgressColor="LightGray" HeightRequest="10" Progress="1" VerticalOptions="End"/>
<ProgressBar Grid.Row="1" Grid.Column="0" ProgressColor="{Binding ColoreUmore}" HeightRequest="10" Progress="{Binding ProgValore}" VerticalOptions="End"/>
<FlexLayout
Grid.Row="2"
Margin="0,5,10,0"
Grid.Column="1"
BindableLayout.ItemsSource="{Binding IconDiaries}"
Wrap="Wrap"
JustifyContent="Start"
Direction="Row"
AlignItems="Start"
AlignContent="Start">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid Padding="0,2,3,0">
<Grid.RowDefinitions>
<RowDefinition Height="18"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="18"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:TintedImage Grid.Row="0" Grid.Column="0" Source="{Binding isSource}" Margin="2" TintColor="{Binding ColoreUmore}"/>
<Label Grid.Row="0" Grid.Column="1" FontFamily="FontM" Text="{Binding id}" TextColor="{DynamicResource TextColor}" Opacity="0.9" FontSize="13" VerticalTextAlignment="Center" Margin="0,0,3,0"/>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
<Label Grid.Row="3" Grid.Column="1" FontFamily="FontM" TextColor="{DynamicResource TextColor}" FontSize="16" Text="{Binding Nota}"/>
Result
Is there any way to turn this FlexLayout into a StackLayout and be able to visualize in the same way?
Use * instead of Auto for your FlexLayout row.
<Grid BackgroundColor="{DynamicResource SfondoElemDiario}" RowSpacing="0.2">
<Grid.RowDefinitions>
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- elements -->
</Grid>

How can I not stretch out my image button in XAML

I have these search bars and image buttons using Xamarin Forms, but the image button is getting stretched out, and I don't know how I can fix it with the XAML set up that I have.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0" Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center"/>
<ImageButton Grid.Row="0" Grid.Column="1"
Margin="4,5,4,4"
Command="{Binding Filter}" Source="filter.png" BackgroundColor="Transparent"></ImageButton>
</Grid>
The problem is, that if I set the image button to a specific width, to make it universal among devices, I don't know how to tell XAML to just stretch the search bar up to the image. What can I do?
I have tried with shared code , however it works in my local site . I think difference should be the PNG image . To clearly show the size of the ImageButton, I added a background color to illustrate it.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect as follow :
Here is the PNG image info :
However , I can reproduce your problem with my PNG image . If I set Aspect="Fill" and Width of Column is * as follow :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Aspect="Fill"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effects :
About Solution , I have found three here :
First , if you can get a standard PNG file as minie , there will no problem .
Second , you can add Aspect="AspectFit" into ImageButton as Jason's suggestion .But that's not enough for your PNG image .You also need to set Width for its Column as follow :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Aspect="AspectFit"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect :
Third , based on my reproduced code , adding HorizontalOptions="Center" for ImageButton also can solve it .
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
HorizontalOptions="Center"
Aspect="Fill"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect :
Although the image of three solutions shows the same , however the Bounds of their backgroud Frame is different .
use the Aspect property
<ImageButton Aspect="AspectFit" ...

Different TapGestureRecognizer for each row

<ContentView>
<Grid InputTransparent="True">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Spacing="0"
Grid.Row="0"
VerticalOptions="Center">
<Label Text="Algebra"/>
<Label Text="number 1" />
</StackLayout>
<Switch IsToggled="True"
VerticalOptions="Center"
Grid.Row="1"
Grid.Column="1"
/>
<StackLayout Spacing="0"
Grid.Row="1"
VerticalOptions="Center">
<Label Text="Arithmetics" />
<Label Text="number 2" />
</StackLayout>
<Switch IsToggled="True"
VerticalOptions="Center"
Grid.Column="1"
/>
</Grid>
</ContentView>
I have two rows with each having 2 labels and a switch. How can I invoke two different Tap events, for each row. Something like this:
<ROW1?.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped1" />
</ROW?.GestureRecognizers>
<ROW2?.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped2" />
</ROW?.GestureRecognizers>
I'm new, but it seems Switch toggle doesn't work while in grid, which is strange.
UI image:
Since you can't simply apply a gesture to an entire grid row,
I decided to just use Switch built-in functionality for my UI.
And all I did was add two different methods for each Switch:
<Grid InputTransparent="True">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Spacing="0"
Grid.Row="0"
VerticalOptions="Center">
<Label Text="Algebra"/>
<Label Text="number 1" />
</StackLayout>
<Switch IsToggled="True"
Toggled="method2"
VerticalOptions="Center"
Grid.Row="1"
Grid.Column="1"
/>
<StackLayout Spacing="0"
Grid.Row="1"
VerticalOptions="Center">
<Label Text="Arithmetics" />
<Label Text="number 2" />
</StackLayout>
<Switch IsToggled="True"
Toggled="method2"
VerticalOptions="Center"
Grid.Column="1"
/>
</Grid>

How to design a button from bottom of my Grid in Xamarin.forms

I have a grid view and I want to add a button in bottom of my screen
I have used following code:
[![enter image description here][1]][1]
<Grid>[![enter image description here][2]][2]
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="88*"/>
<RowDefinition Height="12*"/>
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0" BackgroundColor="White">
<Grid Grid.Column="1" Grid.Row="0" BackgroundColor="White">
<Grid Grid.Row="1" BackgroundColor="#f24245" HorizontalOptions="FillAndExpand">
<Button Text="Lookupjshgkdfjghkdjfghdkjfhgdlfkjghfk" HorizontalOptions="FillAndExpand" TextColor="White" FontSize="Large" BackgroundColor="#f24245"/>
</Grid>
</Grid>
[1]: https://i.stack.imgur.com/vsEn9.png
[2]: https://i.stack.imgur.com/TazCg.png
Please Add Grid.ColumnSpan="2" Like,
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="88*"/>
<RowDefinition Height="12*"/>
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0" BackgroundColor="White">
<!--Place you code Here-->
</Grid>
<Grid Grid.Column="1" Grid.Row="0" BackgroundColor="White">
<!--Place you code Here-->
</Grid>
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BackgroundColor="#f24245" HorizontalOptions="FillAndExpand">
<Button Text="Lookupjshgkdfjghkdjfghdkjfhgdlfkjghfk" HorizontalOptions="FillAndExpand" TextColor="White" FontSize="Large" BackgroundColor="#f24245"/>
</Grid>
</Grid>
Use VerticalOptions="End"
Example:
<Grid Padding="20" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="0.7*" />
<RowDefinition Height="0.3*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- row 0 -->
<Image Grid.Row="0" Source="icon-76.png" WidthRequest="150" HeightRequest="150" />
<!-- row 1 -->
<StackLayout Grid.Row="2" VerticalOptions="End">
<Button Margin="0,5,0,5" Text="Button at the bottom" BackgroundColor="#4a4acd" TextColor="White" FontAttributes="Bold" />
</StackLayout>
</Grid>
This will give you the following view:

How to Create two button in Bottom of the screen

I want to create two buttons in the bottom of the screen using Xamarin.Forms and XAML like the image below:
I've tried to use a GridView but it's getting padding and space from two buttons.
This is how I've tried so far:
<Grid RowSpacing="0"
ColumnSpacing="0"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Grid.Column="0"
Text="SignUp"
FontSize="Large"/>
<Button Grid.Row="1" Grid.Column="1"
Text="LogIn"
FontSize="Large"/>
</Grid>
Try setting the Padding and Margin properties on the Gridview and Padding on the Buttons to 0. IE,
<GridView Padding="0" Margin="0" ... >
...
<Button Margin="0" ... />
I believe that buttons will not provide the desired design, once it has an inner padding, rounded corners and a mandatory uppercase on text (On Android, at least) that you can't change.
Maybe using expanded labels and gesture Recognizers give you a better fit.
Try this:
<Grid ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0"
Text="Signup"
TextColor="White"
FontSize="22"
BackgroundColor="Red"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SignupCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label Grid.Column="1" Grid.Row="0"
Text="Login"
TextColor="White"
FontSize="22"
BackgroundColor="Green"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginCommand}"/>
</Label.GestureRecognizers>
</Label>
</Grid>