I have implemented a list in a Xamarin Forms project, using FlowListView, with three columns in a grid. I want to center the text horizontally and vertically. However, on iOS I am facing issues, as I can't center the text vertically in the last column. On Android it works fine, but for some reason it doesn't work on iOS.
This is how it looks like on Android:
This how it looks like on iOS:
Some of them are centered while others aren't. I know that the height of each row isn't the same, but that's not the reason - Have tested with different heights.
This is the code for the list:
<flv:FlowListView FlowColumnCount="1" SeparatorVisibility="None" HasUnevenRows="True"
FlowItemsSource="{Binding PlayersList}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Grid ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" FontSize="Medium" Grid.Column="0" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding Period}" FontSize="Medium" Grid.Column="1" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Label Text="{Binding Goals}" FontSize="Medium" Grid.Column="2" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
</Grid>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
As you can see, HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center". What am I missing?
The items I have are from a database.
Related
I'm essentially trying to create a view that displays a list of items underneath an interactable header (a Button and an Image wrapped in a FlexLayout) that sorts that specific column A-Z / Z-A, my problem is that I can't figure out how to line them up neatly and without manually setting the column width in ColumnDefinition.
Normally I'd just set the width to some value but since its going to be cross platform (including tablets) I want to avoid doing that so I don't end up with everything squished to one side if the user decides to use a tablet with a much wider screen, does anyone know any fixes or have any advice on what I could look into trying?
Thanks in advance, and I'll post a snippet of what I'm trying to achieve below
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FlexLayout AlignItems="Center" Grid.Row="0" Grid.Column="0">
<Button Text="Name" FontSize="8" Clicked="QuickSort" Padding="0"/>
<Image Source="" Aspect="AspectFit" HeightRequest="20" WidthRequest="20" IsVisible="False"/>
</FlexLayout>
<FlexLayout AlignItems="Center" Grid.Row="0" Grid.Column="1">
<Button Text="Type" FontSize="8" Clicked="QuickSort" Padding="0"/>
<Image Source="" Aspect="AspectFit" HeightRequest="20" WidthRequest="20" IsVisible="False"/>
</FlexLayout>
<FlexLayout AlignItems="Center" Grid.Row="0" Grid.Column="2">
<Button Text="Cost" FontSize="8" Clicked="QuickSort" Padding="0"/>
<Image Source="" Aspect="AspectFit" HeightRequest="20" WidthRequest="20" IsVisible="False"/>
</FlexLayout>
<ListView ItemSource="{Binding Collection}" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding name}" Grid.Column="0"/>
<Label Text="{Binding type}" Grid.Column="1"/>
<Label Text="{Binding cost}" Grid.Column="2"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
A simple solution is to copy the Grid column declarations into the ItemTemplate's DataTemplate. This makes each item a Grid, whose columns match the outer Grid:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid ColumnDefinitions="*, *, *">
<Label Text="{Binding name}" Grid.Column="0"/>
<Label Text="{Binding type}" Grid.Column="1"/>
<Label Text="{Binding cost}" Grid.Column="2"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
The labels all default to "Row=0", so each item is a one-row Grid.
If you like to make it easier, maybe try some datagrid libraries like https://github.com/akgulebubekir/Xamarin.Forms.DataGrid
I have the following XAML :
<StackLayout>
<Grid IsVisible="{Binding isVisible}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<behaviors:Expander x:Name="MainExpander" CollapseAnimationLength="500" IsExpanded="false" >
<behaviors:Expander.Header>
<Grid HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Frame HeightRequest="40" WidthRequest="40" CornerRadius="20" HorizontalOptions="Start" VerticalOptions="Center" Margin="20" Padding="0" BackgroundColor="Maroon">
<Label Text="{Binding student_initial}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
</Frame>
<StackLayout Grid.Column="2" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Margin="20">
<Label x:Name="StudentName" Text="{Binding student_fullname}"></Label>
<Label x:Name="StudentID" IsVisible="false" Text="{Binding student_unique_id}"></Label>
</StackLayout>
</Grid>
</behaviors:Expander.Header>
<Grid RowSpacing="0" HorizontalOptions="FillAndExpand" HeightRequest="240" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Text="Messages" Clicked="Button_Clicked"></Button>
<Button x:Name="btnTopUp" Grid.Row="1" Text="Quick Topup" Clicked="Button_Clicked" IsVisible="{Binding topup_product_id, Converter={StaticResource IsNotNullOrEmptyConverter}}"></Button>
<Button Grid.Row="2" Text="Payments" Clicked="Button_Clicked"></Button>
</Grid>
<!--TODO: Look at adding a balance for childrens topups?-->
</behaviors:Expander>
</Grid>
</StackLayout>
I am trying to hide and show the grid as follows :
<Grid IsVisible="{Binding isVisible}" ...
The issue is that nothing shows as it looks like the StackLayout is unable to work out how high it needs to be. I can't explicitly set the height property as it depends if the expander is expanded or not. Is there a way to make the stack layout height auto size ? Thank you.
Replace StackLayout with Grid , set its HorizontalOptions and VerticalOptions as Start .
<Grid BackgroundColor="Red" HorizontalOptions="Start" VerticalOptions="Start">
<Grid IsVisible="false" ...
See the following screen shot in all of the scenarios (red color represents the root Grid)
Gird invisible
Grid visible (none-expanded)
Grid visible (expanded)
I have the following ListView -
<StackLayout>
<ListView RowHeight="100" Margin="0,10,2,10">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Margin="0,4,4,4" Padding="0,4,4,4">
<StackLayout Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="testLogo" HeightRequest="45" WidthRequest="45"/>
<StackLayout Grid.Column="1" Orientation="Vertical" >
<Label Text="test" Font="Bold" VerticalOptions="Center" />
</StackLayout>
<Button Grid.Column="2" Text="Login" HorizontalOptions="EndAndExpand" Margin="10,10,10,10"/>
</Grid>
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
This is displaying a columned grid as expected however I cannot float the Button elements to the very right of their respective column.
So currently the display does not look neat in that the buttons position seems to be determined by the string length of the Label elements.
I tried adding VerticalOptions="EndAndExpand" to the Buttons"s however this had no effect.
How can I position the buttons neatly to the far right of their respective columns?
If use Grid as root layout , you can set the width of each Grid item proportionally.
As follow:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
The effect:
In my xaml I'm trying to put padding between my background and my labels/editor and datepicker, but I can't get it right. I've attempted putting the grid inside a grid and put padding or margin on that one. I've tried putting the labels/editors inside a grid/stacklayout, I've even tried negative padding and margin on them.
This is how it looks like without the padding
https://gyazo.com/3809306e3b5a27a5f10058bbc17c295a
But whenever I try to add padding or margin anywhere the editors gets too small and gets clipped on the inside like this:
https://gyazo.com/46f25b9c44e1717bf1fa124eb2b10068
This is how I want it to look like, but I can't get rid of that damn clipping on the editors, why does the editors get clipped but not the label?
I've tried setting margin 0 and padding 0 on the editors specifically, didn't help either.
<!-- Bottom Command Bar -->
<Grid Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="8" BackgroundColor="LightGray" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Padding="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1.5*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" BackgroundColor="White" Text="{Binding QuoteNumber}" TextColor="Black" VerticalOptions="Fill" HorizontalOptions="Fill" />
<Editor Grid.Row="0" Grid.Column="1" BackgroundColor="White" Placeholder="PO Number" TextColor="Black" Text="{Binding PoNumber}" VerticalOptions="Fill" HorizontalOptions="Fill" />
<Editor Grid.Row="0" Grid.Column="2" BackgroundColor="White" Placeholder="Drop Date" TextColor="Black" Text="{Binding DropDate}" VerticalOptions="Fill" HorizontalOptions="Fill" />
<DatePicker Grid.Row="0" Grid.Column="2" MinimumDate="{Binding MinimumDate}" MaximumDate="{Binding MaximumDate}" Date="{Binding DropDate}" BackgroundColor="{StaticResource ThemeBkColor}" TextColor="White"/>
<Editor Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" BackgroundColor="White" Placeholder="Comment" TextColor="Black" Text="{Binding Comment}" VerticalOptions="Fill" HorizontalOptions="Fill"/>
<Label Grid.Row="0" Grid.Column="3" VerticalOptions="Center" HorizontalOptions="Center" FontSize="32" Text="{Binding TotalOrderValue, StringFormat='{0:C2}'}"/>
<Button Grid.Row="1" Grid.Column="3" Margin="10,0,10,2" VerticalOptions="Fill" HorizontalOptions="Fill" Text="SUBMIT PART ORDER" Command="{Binding SubmitJourneyCommand}" BackgroundColor="{StaticResource ThemeBkColor}" TextColor="White" />
</Grid>
Within your Change the value from * to AUTO
From there you can use 'padding' or 'margin' on either the main Grid control or the individual Row elements and controls within them.
How do I center listview items within a Xamarin.Forms app?
The listview items are currently left-aligned.
I want them to be center-aligned.
I have the following code:
<ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Results}" HorizontalOptions="Center">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstName}" />
<Label Grid.Row="0" Grid.Column="1" Text="{Binding LastName}" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Scott the Grid always expands to occupy 100% of the available space. There is no way as far as I can tell to override this even explicitly setting a widthrequest on the grid doesn't even seem to help.
I assume you have a larger layout requirement your attempting to satisfy as centering first and Last name in a listView would be better accomplished with a Stacklayout instead of a grid.
IE
<ViewCell.View>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding FirstName}" HorizontalOptions="EndAndExpand"/>
<Label Text="{Binding LastName}" HorizontalOptions="StartAndExpand"/>
</StackLayout>
</ViewCell.View>
But assuming you really need a Grid then I can offer only 1 addition to Tomasz's suggestion.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition />
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding FirstName}" HorizontalOptions="End"/>
<Label Grid.Row="0" Grid.Column="2" Text="{Binding LastName}" />
</Grid>
This create two Columns on the outside to eat up the space forcing the names to the middle.
Without having actually tried it...
Your cell view is <Grid HorizontalOptions="Center">, but the Grid itself is expanded to fit the cell, so the HorizontalOptions there is inconsequential.
You need to put a secondary container inside that Grid that will be centered,
something like:
<ViewCell.View>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalOptions="Center">
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstName}" />
<Label Grid.Row="0" Grid.Column="1" Text="{Binding LastName}" />
</StackPanel>
</Grid>
</ViewCell.View>
You could also try (if the above doesn't work) adding 3 columns (and 3 rows for vertical alignment) to the Grid with sizes (auto)-(*)-(auto) and putting the StackPanel in the center cell.
Maybe this way:
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstName}" HorizontalOptions="Center"/>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding LastName}" HorizontalOptions="Center"/>
EDITED:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstName}" HorizontalOptions="Center"/>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding LastName}" HorizontalOptions="Center"/>
Just by adding HorizontalOptions="Center" to Label worked for me, good luck
<ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Results}" HorizontalOptions="Center">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Label HorizontalOptions="Center" Grid.Row="0" Grid.Column="0" Text="{Binding FirstName}" />
<Label HorizontalOptions="Center" Grid.Row="0" Grid.Column="1" Text="{Binding LastName}" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>