Notice the two buttons below. The first is in a StackLayout, and the second is in a 1x1 grid cell. The first obeys the HeightRequest property, but the second will not.
How can I control the size of a Button inside of a GridCell?
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SimpleApp"
x:Class="SimpleApp.MainPage">
<StackLayout>
<Button Text="Button"
HeightRequest="30"
HorizontalOptions="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Text="Button"
HeightRequest="30"
HorizontalOptions="Center"
Grid.Row="0" Grid.Column="0" />
</Grid>
</StackLayout>
</ContentPage>
You need to change <RowDefinition Height="200" /> to <RowDefinition Height="*" /> to take in consideration your button size.
If you really want the row to have that size, simply set VerticalOptions="StartAndExpand" in your button XAML code.
Alternatively, you can set <RowDefinition Height="200" /> to <RowDefinition Height="Auto" /> if you want to set this to the default button height. as using <RowDefinition Height="200" /> will take any unused space.
Related
I have a Xamarin.Forms app with a page that show an image and some other elements. The image is a png and on some screens it is too large for it to show unscaled while all the other elements also show.
My question is: Is there any way to get Xamarin.Forms to automatically scale the image down in order to fit everything on screen?
I have a small example to show the problem:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PocImageScaling"
x:Class="PocImageScaling.MainPage">
<StackLayout x:Name="stack1" BackgroundColor="Gray" Spacing="0">
<BoxView x:Name="box1" HeightRequest="200" BackgroundColor="Yellow" />
<Image x:Name="img1" Source="infoscreen_graphic.png" Aspect="AspectFit"/>
<BoxView x:Name="box2" HeightRequest="200" BackgroundColor="Olive" />
<BoxView x:Name="box3" HeightRequest="50" BackgroundColor="Yellow" />
</StackLayout>
</ContentPage>
and in code-behind I have
protected override void OnAppearing()
{
base.OnAppearing();
Debug.WriteLine($"page.Height = {this.Height}");
Debug.WriteLine($"stack1.Height = {stack1.Height}");
Debug.WriteLine($"box1.Height = {box1.Height}");
Debug.WriteLine($"img1.Height = {img1.Height}");
Debug.WriteLine($"box2.Height = {box2.Height}");
Debug.WriteLine($"box3.Y = {box3.Y}, box3.Height = {box3.Height}");
}
What I see on run-time on an iPhone SE is
page.Height = 568
stack1.Height = 568
box1.Height = 200
img1.Height = 152
box2.Height = 200
box3.Y = 552, box3.Height = 50
The yellow box3 is almost not visible at the bottom and thus goes beyond the bounds of the StackLayout and the ContentPage.
I would have liked instead that the Image would shrink enough for everything to be on-screen.
If you want the image to scale and only take up the available space I would switch to a Grid instead of a StackLayout.
<Grid x:Name="grid1" BackgroundColor="Gray" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<BoxView x:Name="box1" HeightRequest="200" BackgroundColor="Yellow" />
<Image Grid.Row="1" x:Name="img1" Source="AppIcon" Aspect="AspectFit" BackgroundColor="Pink"/>
<BoxView Grid.Row="2" x:Name="box2" HeightRequest="200" BackgroundColor="Olive" />
<BoxView Grid.Row="3" x:Name="box3" HeightRequest="50" BackgroundColor="Yellow" />
</Grid>
The <RowDefinition Height="Auto"/> will adjust to your set HeightRequest of the view in that row and the <RowDefinition Height="*"/> will then fill the available space left, which should let everything fit on the screen.
I wanted to have most rows defined xaml code and only one added programmatically in code-behind, but I am not able to do it.
Here is my XAML simplified code:
<Grid x:Name="gridTest">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
</Grid>
<Label Grid.Row="0" Text="row 0"></Label>
<Label Grid.Row="1" Text="row 1"></Label>
And in my code-behind:
gridTest.Children.Add(new Label { Text = "row 2" }, 0, 2);
The output is just "row 2"
Is this really impossible or am I missing something?
Tks
your XAML labels need to be within your <Grid></Grid> tags
<Grid x:Name="gridTest">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="row 0"></Label>
<Label Grid.Row="1" Text="row 1"></Label>
</Grid>
I have a grid area and I would like for that to be filled from top to bottom with the background green color:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="8*" />
<RowDefinition Height="72*" />
<RowDefinition Height="10*" />
</Grid.RowDefinitions>
Here is Row 2
<Grid Grid.Row="2" HorizontalOptions="FillAndExpand" VerticalOptions="Center" BackgroundColor="#EEEEEE">
<Grid Padding="10,10,10,10" VerticalOptions="FillAndExpand"
BackgroundColor="Lime"/>
</Grid>
What I get with this code is a white area that's the correct size of the grid but there's just a small green line in the middle.
How can I make the grid fill completely?
The way to achieve this is to set Background attribute of tag "Grid" to your color of choice.
<Grid x:Name="phraseGrid" BackgroundColor="Green" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="0,20,0,0" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="8*" />
<RowDefinition Height="72*" />
<RowDefinition Height="10*" />
</Grid.RowDefinitions>
<Grid Grid.Row="2" x:Name="buttonGrid" HorizontalOptions="FillAndExpand" VerticalOptions="Center" BackgroundColor="#EEEEEE">
<Grid IsVisible="{Binding ButtonGridVisible, Converter={StaticResource InverseBoolConverter} }" Padding="10,10,10,10" VerticalOptions="FillAndExpand" BackgroundColor="Lime">
</Grid>
You can create an AbsoluteLayout as a root.
And put your background grid first on the AbsoluteLayout with full width and height.
Then add your content on the same AbsoluteLayout as well.
I'm new to Xamarin so excuse me if this is very obvious.
I added a Grid to my ContentPage. I want the grid to occupy the entire ContentPage, which I assume is the full size of the device. In my case I'm testing an iPhone 6S simulator.
The first row should be 7.58% of the total height of the Grid and the last one should fill in the rest. I add the label to see where the bottom of the last row is and it shows all the on the top. It looks like it's ~7% from the top which means it's the bottom of the 1st row.
<Grid x:Name="layoutGrid" HorizontalOptions="Fill" VerticalOptions="Fill">
<Grid.RowDefinitions>
<RowDefinition Height=".0758*"/>
<!-- Logo -->
<!-- Remaining Space -->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".154*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width=".154*" />
</Grid.ColumnDefinitions>
<Image Aspect="Fill" Source="{local:ImageResource App1.Resources.background.png}" Grid.ColumnSpan="3" Grid.RowSpan="11"/>
<Image Aspect="AspectFit" x:Name="settingsImage" Grid.Column="2" Grid.Row="0" Source="{local:ImageResource App1.Resources.settings-17-xxl.png}" HorizontalOptions="End"/>
<Label x:Name="lblTest" Grid.Row="1" Text="Bottom" TextColor="White" VerticalOptions="End" HorizontalOptions="Center" FontSize="18"/>
It looks like you are placing two items in the same space, which you can not do in a grid. IOW the first image in the XAML (it seems you want this across the entire grid?) does not have a row and column set, but defaults to row/column 0. Then your column span is 3 and row span is 11(?). You only have two rows, so that makes no sense. Also you then can not place the second image in Row 0 column 2 as that is already occupied by the first image. You may want to set the first image as a page background. Or use an Absolute or Relative layout in which you can overlay items. A grid does not allow overlaid items as far as I know. Also you have your vertical options for the label set to "End" which will place it at the bottom of row 1, not the top. Try the following XAML to see if that is closer to what you want:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"
BackgroundImage="{local:ImageResource App1.Resources.background.png}">
<Grid x:Name="layoutGrid" HorizontalOptions="Fill" VerticalOptions="Fill">
<Grid.RowDefinitions>
<RowDefinition Height=".0758*"/>
<!-- Logo -->
<!-- Remaining Space -->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".154*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width=".154*" />
</Grid.ColumnDefinitions>
<Image Aspect="AspectFit" x:Name="settingsImage" Grid.Column="2" Grid.Row="0" Source="{local:ImageResource App1.Resources.settings-17-xxl.png}" HorizontalOptions="End"/>
<Label x:Name="lblTest" Grid.Row="1" Text="Bottom" TextColor="White" VerticalOptions="Start" HorizontalOptions="Center" FontSize="18"/>
</Grid>
</ContentPage>
Hi Guys probably very easy question for Xamarin expert I am trying to vertically center align stacklayout control and it is working fine in android mobile but not working in windows mobile device. My code is below
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="aa.Views.MainPage">
<ScrollView>
<StackLayout Orientation="Vertical" VerticalOptions="CenterAndExpand"
Padding="20" Spacing="10">
<Entry x:Name="enEmail" Placeholder="Email"></Entry>
<Entry x:Name="enPassword" IsPassword="True" Placeholder="Password"></Entry>
<Button Text="Login" Clicked="OnClicked_btnLogin" x:Name="btnLogin"></Button>
<Button Text="Register" Clicked="OnClicked_btnRegister" x:Name="btnRegister"></Button>
</StackLayout>
</ScrollView>
</ContentPage>
For more details please have a look at the attached images and help me how would i align it in center of screen for windows phone
its StackLayout: puts views consecutive one another. If you want to move buttons to down side use Grid instead like:
<Grid RowSpacing="10"><!--RowSpacing gives some space between rows-->
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <!--You can also use constant size also-->
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <!--This fill the empty space-->
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Entry Grid.Row="0" Placeholder=" Email"/>
<Entry Grid.Row="1" Placeholder=" Password" IsPassword="True"/>
<Button Grid.Row="3" Text="Login" />
<Button Grid.Row="4" Text="Register" />
</Grid>
Try the code below, it will give you a scroll view plus your fields will be aligned to the center
<ScrollView>
<AbsoluteLayout>
<StackLayout Orientation="Vertical" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" x:Name="maincontent" Spacing="0">
<StackLayout Orientation="Vertical" VerticalOptions="CenterAndExpand"
Padding="20" Spacing="10">
<Entry x:Name="enEmail" Placeholder="Email"></Entry>
<Entry x:Name="enPassword" IsPassword="True" Placeholder="Password"></Entry>
<Button Text="Login" Clicked="OnClicked_btnLogin" x:Name="btnLogin"></Button>
<Button Text="Register" Clicked="OnClicked_btnRegister" x:Name="btnRegister"></Button>
</StackLayout>
</StackLayout>
</AbsoluteLayout>
</ScrollView>