Xamarin.Forms: Add padding to label in grid? - xamarin

A grid cell looks like this:
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
There are 2 columns, and each column is 50% of the width. With the xaml above, the whole cell (half the row) will be painted red.
It looks like this:
Can I add left and/or right padding just to Grid.Row="0" and Grid.Column="1" so that the column is still 50% width but not the label? What I don't want to do is change the grid structure (ie. add more columns).
The desired result is something like this, but without having to add more columns or change column size:

Just add HorizontalOptions="Center" if you just want to place in the middle of the column. In this method, if the label's text is increased, the space around the label decreases.
If you want to have a certain amount of space around the label, you should set Margin for Label.
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
Margin="20,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />

You can put the label in a StackLayout and set the padding of it.Such as:
<StackLayout Grid.Row="0" Grid.Column="1" Padding="10,0,10,0">
<Label
Text="text"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
</StackLayout>
PS:Differernt from padding in CSS (top-right-buttom-left),the order of the padding in xamarin is left-top-right-buttom.
For more detail you can refer Margin and Padding

If I understood that correctly you need margin and not padding. For the very same reason, you won't find a padding property in Label, like many other views in Xamarin Forms.
This should serve your purpose.
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="1"
Margin="20, 0, 20, 0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="16"
TextColor="White"
BackgroundColor="red" />
To understand how padding and margin works in details, you can check this link
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/margin-and-padding

Related

How to make Grid Row dynamic in CollectionView control of .Net MAUI?

I'm trying to achieve dynamic row height in CollectionView control, so that when ever I have more text for a particular property it will extend the height of the frame automatically.
I have tried with ListView as well using HasUnEvenRow property "true" but with that also it's not working.
Here is my code:
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid RowDefinitions="*,60" BackgroundColor="{StaticResource PageBackgroundColor}" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<CollectionView Grid.Row="0" HorizontalOptions="Fill" VerticalOptions="Fill"
ItemsSource="{Binding Inspections}"
VerticalScrollBarVisibility="Always"
ItemsLayout="VerticalList" ItemSizingStrategy="MeasureAllItems">
<CollectionView.ItemTemplate>
<DataTemplate>
<Frame Padding="15" HasShadow="False">
<Grid HorizontalOptions="Fill"
VerticalOptions="Fill"
BackgroundColor="White"
RowSpacing="25"
RowDefinitions="Auto,Auto,Auto"
ColumnDefinitions="*,Auto">
<StackLayout
Orientation="Horizontal"
Grid.Row="0"
Grid.Column="0">
<Label Text="{Binding Path=BusinessName}"
Style="{StaticResource LabelTitleStyle}" />
<Grid Padding="15,0,0,0">
<baseChip:Chip
HorizontalOptions="Fill" VerticalOptions="Fill"
Style="{StaticResource ChipContainer}"
HasShadow="False"
BackgroundColor="{Binding Path=ChipBackgroundColor}">
</baseChip:Chip>
<Label
Text="{Binding Path=ChipText}"
Style="{StaticResource ChipLabel}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
TextColor="{Binding Path=ChipTextColor}"/>
</Grid>
</StackLayout>
<Image
Grid.Row="0"
Grid.Column="1"
HorizontalOptions="End"
VerticalOptions="Center"
Aspect="AspectFit">
<Image.Source>
<FontImageSource Glyph="{x:Static helper:MaterialFontHelper.FilePdfBox}"
Color="{StaticResource DarkGray}"
Size="20"
FontFamily="MaterialDesignIcons"/>
</Image.Source>
</Image>
<Grid Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="Auto, Auto"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Inspection Type"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="ksd kahdkahd kahd kahd aojsoiud aasjlj sdlkja dlkja da asdadas alsajdlaksjdlajd alsjdalkjd alksjd sa"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Primary Inspector"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource LabelValueStyle}" >
<Label.FormattedText>
<FormattedString>
<Span Text="{Binding Path=InspectorFirstName}"/>
<Span Text=" "/>
<Span Text="{Binding Path=InspectorLastName}"/>
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
<Grid Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
RowDefinitions="*, *"
ColumnDefinitions="*, *">
<Label
Grid.Row="0"
Grid.Column="0"
Text="Scheduled Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="0"
Text="{Binding Path=ScheduledStartDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
<Label
Grid.Row="0"
Grid.Column="1"
Text="Completed Date"
Style="{StaticResource LabelKeyStyle}" />
<Label
Grid.Row="1"
Grid.Column="1"
Text="{Binding Path=CompletionDate, Converter={StaticResource dateFormatter},ConverterParameter='long'}"
Style="{StaticResource LabelValueStyle}" />
</Grid>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout
Grid.Row="1"
VerticalOptions="End"
HorizontalOptions="FillAndExpand"
BackgroundColor="{StaticResource White}">
<controlTemplate:BeginInspectionContentView></controlTemplate:BeginInspectionContentView>
</StackLayout>
</Grid>
</StackLayout>
Output & expected output image attached here:
How to achieve dynamic height for this UI? Any help or suggestions are welcome.
There are three solutions to this problem:
You can change CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate. Then you don't need to set Height for item or FlexLayout because all are dynamic.
You can set a value to collectionView.HeightRequest using MVVM. When item increase, the height will increase as well. For more details about this solution, you may refer to the link.
You can use CollectionView.Behaviors to calculate the Height of every item to increase the height of ContentView. For more details about this solution, you may refer to the link.
You have Grid. With StackLayout. With Grid. With Small Grids inside it.
I will put aside for now, that this is extremely bad for rendering. (It is serious problem however...)
None of the expected output justify this organization.
If you need for element to occupy 2 columns, you can use columns span 2.
Before anything else, please combine all 4 grids in a single grid.
After you are done with that, limit your VisualElements height, or, even better, limit the content you are putting in them. (Because cut content looks bad. You should be using something like "show more" link, that opens popup or whatever).
If you have any questions, please ask.
Edit: Let me clarify:
You have the same Grid code. Most important part - columns are * , * , and rows are auto height. And every 2 rows, you create another GRID, that is copy of the first GRID.
This is extremely counterproductive.
Also, just because you can do something, and it is "working in xamarin", it doesn't mean that you should do it.
First, put everything in the same grid, instead of nesting it and copying grids, then you can start working on CLIP/Height limit/etc.
(Recommending you to test it on IOS, because once you get it running fine there, it is much easier to fine-tune it for other platforms, than the other way around.)

Xamarin Forms Grid.Row Auto --> Still Shows Scrollbar in Grid Item

I have a slight problem with XamarinForms, which I am fairly new with.
I do have a grid with several Items in it (ListView, Label, Stacklayout, Listview).
I thought setting RowDefinitions = "Auto" for each row, would make the whole Page scrollable.
But instead I have a scrollbar on each individual listView.
I have added a snippet of my code with one of the listViews inside.
How do I get the listViews shown in their full size and the scrollbar be for the whole page?
I have already tried a scrollview instead of the grid, but it did not work.
Picture of Content in Emulator
Picture of Whole Page
Xamarin Forms:
<Grid
Padding="10"
RowDefinitions="Auto,Auto,Auto,Auto"
ColumnDefinitions="*"
>
<Label Padding="20" FontAttributes="Bold" FontSize="40" Text="{Binding DisplayName}" Grid.Row="0"/>
<ListView ItemsSource="{Binding News}"
HasUnevenRows="True"
IsPullToRefreshEnabled="False"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding DateTimeString}"/>
<Label Text="{Binding Text}" MaxLines="4"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Header>
<Grid ColumnDefinitions="*,Auto"
Padding="10"
VerticalOptions="Center">
<Label Text="News"
Grid.Column="0"
FontAttributes="Bold"
FontSize="32"/>
<Label Text="mehr Anzeigen"
Grid.Column="1"
HorizontalTextAlignment="End"/>
</Grid>
</ListView.Header>
</ListView>
You can put the items in ScrollView which is capable of scrolling its content.
refer to: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/scrollview

How can I move the relative position of an image in a grid?

I am creating a car app that lists cars and their prices, model, speed, etc. I wanted to position the price over an image of the car, like so:
To do this, I created a grid and allowed the image to fill the entire thing while forcing the text (with a frame around it) into a lower column/row. However, I am ending up with white space on the top of the graph. Take a look. I set the grid to a background color of blue for easier viewing.
The issue here is the aspect ratio, because an image that did fill the entire grid would cut off the sides. The size of the whitespace is equivalent to the overlay, so if I had the overlay any lower that would result in more whitespace on both sides.
Note: Some of the cars have different aspect ratios, so this has to be a fix that would work for other images as well.
Note 2: This has to be a relative position fix, since obvious methods like setting the image's margin to -100 wouldn't work on other resolution screens and would probably get me fired.
The question: How can I relatively (e.g. make it work on every screen) force the image to the top of the page while still keeping the same aspect ratio and keeping the overlay?
Here's the front-end.
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="63*"/>
<ColumnDefinition Width="35*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3" Grid.RowSpan="2"/>
<Frame BackgroundColor="White" CornerRadius="5" Grid.Column="1" Grid.Row="1">
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
Move your frame not the image.
Set Grid content in one row.
Set Frame VerticalOptions to End
Set Frame HeightRequest and Margin (minus value).
Set bottom StackLayout VerticalOptions to FillAndExpand
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue" ColumnDefinitions="63*, 35*, 2*">
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3"/>
<!-- Shape the Frame here -->
<Frame HeightRequest="40" Margin="0,0,0,-20" VerticalOptions="End"
BackgroundColor="White" CornerRadius="5" Grid.Column="1" >
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15" VerticalOptions="FillAndExpand">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>

How to show each record of list one by one in page when swipe up/down in xamarin forms

I have a list of many records and i want to show each record on one single page.
What i want is, When we do swipe up from bottom of the page, next record in list should show with animation. similarly, when we do swipe down from top of the page, previous record in list should show with animation.
I don't know how to achieve this. hope for better solution
Caraousel View with orientation and snap points should give you desired results
<CarouselView BindingContext="{x:Reference BottomTabGridPageXaml}" ItemsSource="{Binding StudentList}"
VerticalOptions="FillAndExpand">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" SnapPointsType="MandatorySingle"/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout VerticalOptions="FillAndExpand">
<Label Text="{Binding Id}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Name}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Number}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<Label Text="{Binding Age}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>

Align two Labels to be inline in XAML

I'm styling in Xamarin Forms. I have problem with align Vertical 2 label other size:
This is my XAML code:
<StackLayout HorizontalOptions="EndAndExpand" Grid.Row="0" Grid.Column="1">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="03" FontSize="42" FontAttributes="Bold" Style="{StaticResource LabelNormal}" HorizontalTextAlignment="End" VerticalTextAlignment="End" />
<Label Text="\20" Style="{StaticResource LabelNormal}" HorizontalTextAlignment="End" VerticalTextAlignment="End" />
</StackLayout>
<Label Text="Chưa xử lý" Style="{StaticResource LabelNormal}" HorizontalTextAlignment="End" />
</StackLayout>
I want "30" and "/20" are straight on bottom. How I can do it?
Resovled
This is my simple solution. I added Margin-bottom is "-7" and it worked.
<Label Text="03" FontSize="42" FontAttributes="Bold" Style="{StaticResource LabelNormal}" HorizontalTextAlignment="End" VerticalTextAlignment="End" Margin="0,0,0,-7" />
While your solution is working it might be not the best, please consider the next topics:
Negative values in padding can introduce inconsistent side effects on different screens and platforms. It should be considered as a very dirty hack and should be avoided.
Performance. It seems that you overused StackLayout. Try Grid, it will reduce the amount of UI elements to render and will increase the loading time.
Good luck!

Resources