I'm currently styling a listview, in which I want to add a separating space between each entity in the ListView. For doing that, I use a Grid for each ViewCell with Margin="0,0,0,10".
I can get my elements to fit inside the grid row, but if I add a padding to the row, to give it some top/bottom spacing, it just scales down the text inside the grid.rowuntil eventually, it disappears.
<ListView Margin="10" HasUnevenRows="false" BackgroundColor="Fuchsia" x:Name="deviceList" ItemsSource="{Binding Devices}" CachingStrategy="RecycleElement" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Silver" Margin="0,0,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" VerticalOptions="Center" RowSpacing="10">
<local:IconView Source="BLE.png" Foreground="#3b5998" WidthRequest="30" HeightRequest="30" />
</Grid>
<Grid Grid.Row="0" Grid.Column="1" VerticalOptions="Center">
<Label Text="{Binding Name}" TextColor="Black" />
</Grid>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
How do I add padding to my Grid.Row without scaling down the child elements?
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 image below which I have tried to design in XAML- Xamarin forms.
The xaml code is as follows:
<ListView x:Name="myList" HasUnevenRows="true" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="0,0,0,8" BackgroundColor="#edeeef" BorderColor="#edeeef">
<Frame.Content>
<Frame OutlineColor="Transparent" BackgroundColor="White">
<Frame.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<StackLayout Orientation="Vertical" Grid.Row="0" Grid.Column="0">
<Label Text="{Binding ItemName}"
TextColor="Black"
FontFamily="OpenSans-Light"
FontSize="16"
HorizontalOptions="FillAndExpand"/>
<Label Text="Engine coolant temperature sesnor 1 circuit intermittent (DTC Confirmed)" FontSize="11" HorizontalOptions="StartAndExpand"/>
<StackLayout Orientation="Horizontal">
<Button Text="OBD" />
<Button Text="CUS" />
</StackLayout>
</StackLayout>
<BoxView
VerticalOptions="Fill"
HorizontalOptions="End"
WidthRequest="1"
HeightRequest="5"
Color="Blue"
Grid.Row="0"
Grid.Column="1"/>
<ffsvg:SvgCachedImage
Aspect="AspectFit"
VerticalOptions="Center"
Source="Bin.png"
Grid.Column="2"
Grid.Row="0"
/>
</Grid>
</Frame.Content>
</Frame>
</Frame.Content>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The issue that I am having is that I am unable to draw the vertical right line separating the content and the square red box on the right.
When I am adding the image, it is adding extra padding on the bottom.
Can someone please help me to align the components properly as in the image above in XamarinForms? Thanks.
Your design is quite messed up and should be cleaned up
Within the ViewCell, you have two nested Frames, which causes the main issue: There is a padding on the inner Frame that and on the outer one, which prevent the separator to take the full height
A nested Grid and StackLayout is most likely not necessary and definitely detrimental for your performance
Suggestions:
Remove the outer Frame and add a Margin to the inner one
Set the Padding of the inner frame to 0
Remove the StackLayout wrapped in the Grid and add the controls to the Grid
Add the Grid.RowSpan and Grid.ColumnSpan for controls that take more height/width in the Grid
Your XAML within the ViewCell will look like this:
<Frame Padding="0"
Margin="5"
BorderColor="Transparent"
BackgroundColor="White"
CornerRadius="10">
<Grid ColumnSpacing="0" RowSpacing="5" Padding="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="ItemName"
TextColor="Black"
FontFamily="OpenSans-Light"
FontSize="16"
HorizontalOptions="FillAndExpand"
VerticalOptions="End"
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="2"
Margin="10,10,10,0" />
<Label Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="2"
Text="Engine coolant temperature sesnor 1 circuit intermittent (DTC Confirmed)"
FontSize="11"
HorizontalOptions="StartAndExpand"
Margin="10,0,0,0" />
<Button Text="OBD"
VerticalOptions="End"
HorizontalOptions="Start"
Grid.Row="2"
Grid.Column="0"
Margin="10,0,5,10" />
<Button Text="CUS"
VerticalOptions="End"
HorizontalOptions="Start"
Grid.Row="2"
Grid.Column="1"
Margin="0,0,10,10" />
<BoxView VerticalOptions="Fill"
HorizontalOptions="End"
WidthRequest="1"
Color="LightPink"
Margin="0"
Grid.Row="0"
Grid.Column="2"
Grid.RowSpan="3" />
<Image Aspect="AspectFit"
VerticalOptions="Center"
HorizontalOptions="End"
Source="http://lorempixel.com/output/abstract-q-c-200-200.jpg"
Grid.Column="3"
Grid.Row="0"
Grid.RowSpan="3"
Margin="10"/>
</Grid>
</Frame>
And eventually the design looks like that (There is still space for tweaking, but basically that's it. I've changed the colors a bit for better visibility):
Follow this Code.
<Grid Grid.Row="3" Padding="{StaticResource Padding15050}">
<ListView x:Name="ListViewFood" ItemsSource="{Binding FoodList}" HasUnevenRows="True" ItemSelected="OnSelection" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="{StaticResource Padding510}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Controls:Label x:Name="LabelName" Grid.Row="0" Text = "{Binding Name}" Font="17" TextColor="{StaticResource Black}"/>
<Controls:Label x:Name="LabelDescription" Grid.Row="1" Text = "{Binding Description}" Font="15" />
<Controls:Label x:Name="LabelPrice" Grid.Row="2" Text = "{Binding Price}" Font="15" TextColor="{StaticResource YetiBlue}"/>
</Grid>
<Grid Grid.Column="1">
<Controls:RectangleButton Text="Add" Font="Bold,15" VerticalOptions="Start" HorizontalOptions="EndAndExpand" CommandParameter="{Binding Id}" Clicked="RectangleButton_Clicked"/>
</Grid>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Design like this.
If you want to add a separate line, you just need to add a BoxView in your xaml with WidthRequest=1.
I always use this solution for separating content.
In your case I would suggest to delete HeightRequest in your BoxView.
Question
How can I increase the height of each row in my DataTemplate. I've set the height multiple times in different elements, however the row height doesn't change from the seemingly default height.
What am I missing?
Xaml
<ListView x:Name="ListViewItems">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell Tapped="TapGestureRecognizer_Tapped" Height="400">
<Grid Padding="5" Margin="5" HeightRequest="400">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="400"/>
</Grid.RowDefinitions>
<Label Text="{Binding Title}" Grid.Row="0" Grid.Column="1" FontSize="15"/>
<Image Source="#drawable/cereals.png" Aspect="AspectFill" HeightRequest="400" Grid.Row="0" Grid.Column="0" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Screenshot
If you want to allow a ListView row to set its own height, you need to set the ListView HasUnevenRows property to true.
Just put HasUnevenRows="True"
on the ListView. This should do the trick.
My XAML looks like this:
<StackLayout Orientation="Vertical" HorizontalOptions="Center">
<controls:BindablePicker HorizontalOptions="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Aqua">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:BindablePicker Title="Length" Grid.Row="0" Grid.Column="0" BackgroundColor="White" />
<controls:BindablePicker Title="Units" Grid.Row="0" Grid.Column="1" BackgroundColor="White" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</StackLayout>
Here's what I'm getting: Attempt
This is pretty much what I want, except I want the content centered within the aqua area so everything is centered horizontally. I don't mind if the left cell is right justified and the right cell is left justified.
Note that I'm wanting to add other content beneath this, like labels and other grids, all centered on the page.
Any help would be greatly appreciated. Thanks.
First of all I do not think that you need a row definition in your inner grid since you have only one row.
Secondly for performance sake,do not user "Auto" , just remove the width property from the column definitions.
By doing this both columns will have the same width... I hope ;)
I think if you made your list view like below then it would fix it, but also try it without HorizontalOptions for the controls.
<ListView Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid BackgroundColor="Aqua">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<controls:BindablePicker Title="Length" Grid.Column="0" BackgroundColor="White" HorizontalOptions = "End" />
<controls:BindablePicker Title="Units" Grid.Column="1" BackgroundColor="White" HorizontalOptions = "Start" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Hint: The next release of Xamarin.Forms, which is in the alpha channel now, contains a bindable picker so you do not have to user a 3rd party now.
I have the following ListView in my xaml layout:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="{StaticResource AppName}" Style="{StaticResource TitleTextBlockStyle}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<ListView x:Name="lstStatus">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="12">
<Image Source="ms-appx:///Assets/Logo.png" Margin="12" Width="150" Height="150"></Image>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path='Fullname'}" Style="{StaticResource ListViewItemSubheaderTextBlockStyle}"></TextBlock>
<TextBlock Text="{Binding Path='FormattedCreationTime'}" TextWrapping="WrapWholeWords"></TextBlock>
<TextBlock Text="{Binding Path='Text'}" Style="{StaticResource ListViewItemContentTextBlockStyle}" TextWrapping="WrapWholeWords" Margin="12"></TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
However, I met two problems:
The list is not scrollable when it is longer than the screen.
The TextBlocks does not wrap at all although I already set TextWrapping.
I am pretty new to Windows Phone design. Please tell me where did I do wrong.
The StackPanel takes as much space as it needs. As the ListView grows, the StackPanel expands to allow it to grow, hence you cannot scroll to see the items you don't see on the screen.
Put the ListView in a Grid or limit the Height of the StackPanel.
<Grid Grid.Row="1">
<ListView x:Name="lstStatus">
...
Similar problem occurs in your ItemTemplate, and the fix is also similar.
<DataTemplate>
<Grid Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image ...
<StackPanel Grid.Column="1">
<TextBlock ....
</StackPanel>
</Grid>
</DataTemplate>