Change List View Header and Group Header Vertical Order - c#

Using xamarin forms.
I have list view contains header and group header like below.
<ListView x:Name="Groups" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
SeparatorVisibility="Default" RowHeight="100" HasUnevenRows="True" IsGroupingEnabled="True" Header="">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<TextCell Height="50" Text="{Binding GroupName}" TextColor="White" />
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.Header>
<Grid BackgroundColor="#941a24" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White" x:Name="Order" />
<Label Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White" x:Name="Name"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
//items
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
What is happen is the header of the List View appears Vertically Above the Group Header but I want to show the group header above the header (without changing the list view Binding object) such that every time the group header appears the List view header appears below.

No matters where you define the header/group header in your XAML, it'll be compiled and you'll always get the list header above the group header and items (see more on official docs).
If you want that every time the group header appears the List view header appears below, just change the group header template to be a ViewCell and code the actual 'list header' content inside it.
Something like this:
<ListView x:Name="Groups"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
SeparatorVisibility="Default"
RowHeight="100"
HasUnevenRows="True"
IsGroupingEnabled="True">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Spacing="0">
<Label Text="{Binding GroupName}"
TextColor="White"
VerticalTextAlignment="Center"
VerticalOptions="Fill"
HeightRequest="50"/>
<Grid BackgroundColor="#941a24"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label x:Name="Order"
Grid.Column="0"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
TextColor="White"/>
<Label x:Name="Name"
Grid.Column="1"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
TextColor="White"/>
</Grid>
</StackLayout>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
//items
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I hope it helps you.

Related

Xamarin ListView alternate column color

I need to alternate my ListView columns color so it looks like this.
I was searching Google for any help, and found out that i can put BoxView in the same column with my Label and color that BoxView
My result:
As you can see, i have this annoying white line above BoxViews, which i was not able to remove. My question is how do i remove them? i havent set any paddings and margins, have no clue what is problem.
<ListView x:Name="ListView" ItemTapped="ListView_OnItemTapped" ItemsSource="{Binding FilteredReports, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<BoxView HeightRequest="1" Color="#EDEBE9" IsVisible="true"/>
<Grid HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<BoxView Color="#F7FAFC" Grid.Column="0"/>
<Label Grid.Column="0" FontSize="12" FontFamily="Roboto" TextColor="#162938" Text="{Binding ClientPhone}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
<Label Grid.Column="1" FontSize="12" FontFamily="Roboto" TextColor="#162938" Text="{Binding OfficeName}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
<BoxView Color="#F7FAFC" Grid.Column="2"/>
<Label Grid.Column="2" FontSize="12" FontFamily="Roboto" TextColor="#162938" Text="{Binding BranchName}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You are using a StackLayout and by default it has a Spacing property with a value of 6.
You should set it to 0
<ViewCell>
<StackLayout Spacing = "0" >
<BoxView HeightRequest="1" Color="#EDEBE9" IsVisible="true"/>
<Grid HorizontalOptions="FillAndExpand">
....
</StackLayout>
</ViewCell>

ListView Frames as Grid squares one after another

I am trying to position frame cards as suqares one after another horizontally and can't manage it. I wrapped it in Grid, although grid fills all window size it positions frames one under another. Red color on the screenshot is background of the Grid.
How it looks and how i want it to
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid
HorizontalOptions="FillAndExpand"
BackgroundColor="Red">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Frame
HasShadow="True"
Margin="5"
Padding="10"
CornerRadius="5"
Scale="1"
BackgroundColor="{StaticResource DarkGreyPrimary}">
<Frame.Content>
<StackLayout Orientation="Vertical">
<StackLayout>
<Grid>
<Label Text="{Binding Address}"
FontSize="30"
VerticalTextAlignment="End"/>
<Button Clicked="InfoButtonClicked"
Text=""
FontFamily="FA"
FontSize="30"
WidthRequest="53"
Margin="0, 0, -10, 0"
HorizontalOptions="End"/>
</Grid>
<Image Source="{Binding ImageUrl}"
WidthRequest="300"
Aspect="Fill"/>
</StackLayout>
<StackLayout VerticalOptions="Fill" Margin="10, 0, 0, 0">
<StackLayout VerticalOptions="EndAndExpand">
<Label Text="{Binding Id}"
HorizontalOptions="End"
TextColor="{StaticResource LightGrey}"
FontSize="20"/>
</StackLayout>
</StackLayout>
</StackLayout>
</Frame.Content>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Use CollectionView for that, it supports showing items in a grid.
<CollectionView ItemsLayout="VerticalGrid, 3" ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5">
<Frame
Padding="10"
BackgroundColor="{StaticResource DarkGreyPrimary}"
CornerRadius="5"
HasShadow="True"
Scale="1">
<StackLayout Orientation="Vertical">
<StackLayout>
<Grid>
<Label
FontSize="30"
Text="{Binding Address}"
VerticalTextAlignment="End" />
<Button
Margin="0,0,-10,0"
Clicked="InfoButtonClicked"
FontFamily="FA"
FontSize="30"
HorizontalOptions="End"
Text=""
WidthRequest="53" />
</Grid>
<Image
Aspect="Fill"
Source="{Binding ImageUrl}"
WidthRequest="300" />
</StackLayout>
<Label
Margin="10,0,0,0"
FontSize="20"
HorizontalOptions="End"
Text="{Binding Id}"
TextColor="{StaticResource LightGrey}" />
</StackLayout>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Notice the ItemsLayout="VerticalGrid, 3", the number 3 specifies how many columns to display.
Here's the documentation for the CollectionView (as #Jason mentioned earlier in the comments): https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/layout#vertical-grid

Xamarin - Having problems binding a ObservableCollection within another ObservableCollection in a CollectionView

I have a CollectionView that is bound to a ObserableCollection called UserPermissions.
In that FrontUserPermissionsModel class I have another ObservableCollection called MyPermissions.
I am trying to do something like this:
<CollectionView x:Name="CollectionViewEmployees" Margin="0,10,0,0" ItemsSource="{Binding UserPermissions}" SelectionMode="Single" Grid.Row="0"
SelectionChangedCommand ="{Binding SelectedUSerPermissionsDetailsCommand}" SelectedItem="{Binding SelectedUSerPermission}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="5,3,5,9">
.
.
.
.
<StackLayout x:Name="SettingItemsLayout" Grid.Row="7" BackgroundColor="red" Grid.Column="0" HeightRequest="300" Grid.ColumnSpan="2"
BindableLayout.ItemsSource="{Binding MyPermissions}" HorizontalOptions="FillAndExpand">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52*" />
<ColumnDefinition Width="48*" />
</Grid.ColumnDefinitions>
<Label FontSize="18" Grid.Column="0" BackgroundColor="Green" FontAttributes="Bold" HorizontalTextAlignment="Start" Text="{Binding Title}" TextColor="white" />
<Label FontSize="18" Grid.Column="1" FontAttributes="Bold" HorizontalTextAlignment="Start" Text="{Binding AccessLevel}" TextColor="white" />
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The UserPermission binding is working. But my syntax on how to bind the MyPermissions is incorrect and I am not sure how to fix it. Thanks.
Do you mean you want to let your StackLayout binding an other ObserableCollection in the viewmodel ?
You could use Binding Path :
Maybe something like:
<StackLayout x:Name="SettingItemsLayout" Grid.Row="7" BackgroundColor="red" Grid.Column="0" HeightRequest="300" Grid.ColumnSpan="2"
BindableLayout.ItemsSource="{Binding Source={x:Reference SettingItemsLayout},
Path=BindingContext.MyPermissions}" HorizontalOptions="FillAndExpand">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="52*" />
<ColumnDefinition Width="48*" />
</Grid.ColumnDefinitions>
<Label FontSize="18" Grid.Column="0" BackgroundColor="Green" FontAttributes="Bold" HorizontalTextAlignment="Start" Text="{Binding Title}" TextColor="white" />
<Label FontSize="18" Grid.Column="1" FontAttributes="Bold" HorizontalTextAlignment="Start" Text="{Binding AccessLevel}" TextColor="white" />
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>

listview item text changes on scroll

I have a list view in which i am binding multiple data like labels and image and i have that list in my frame so when list size gets greater then 10 items or so then on scroll my image resizes it self and text of label starts hide unhide.
Here is my xaml:
<ListView
x:Name="list"
SelectionMode="None"
SeparatorVisibility="None"
HasUnevenRows="True"
IsVisible="False"
BackgroundColor="Transparent"
ItemTapped="List_ItemTapped"
CachingStrategy="RetainElement"
>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="10" Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition Height="*"
/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="Auto" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Text="{Binding Note}"
HorizontalOptions="Start"
TextColor="Black"
FontSize="Small"
FontFamily="
{StaticResource BoldFont}"
FontAttributes="Bold">
</Label>
<ImageButton
Grid.Row="0"
Grid.Column="1"
HorizontalOptions="EndAndExpand"
WidthRequest="22"
HeightRequest="22"
Padding="6"
Margin="0,0,0,0"
Clicked="btndelete"
AbsoluteLayout.LayoutBounds="0,0,1,1"
BackgroundColor="Transparent"
Source="close.png">
</ImageButton>
<Label
Grid.Row="1"
Grid.Column="0"
Text="{Binding
NOfQuestions}"
FontSize="12"
FontFamily="
{StaticResource Regular}"
TextColor="White">
</Label>
<Label
Grid.Row="1"
Grid.Column="0"
Margin="15,0,0,0"
Text="{Binding
NOfDigits}"
FontSize="12"
FontFamily="
{StaticResource Regular}"
TextColor="White">
</Label>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is the video of my problem in this video you can see that the list looks good but when i start to scroll it the text starts to hide unhide its size changes the cross image is getting small or big and on deleting the list item all the text disappears
Gif video of my problem please watch this
This behavior of re-rendering the list cells is generally related to the ListView Caching Strategy. It defines how the cells are cached and tries to improve the performance when loading lots of data, but can also screw with the proper display. Try messing up with the CachingStrategy. In past experience, setting it to "RecycleElement" solved render problems.
Also, check this link for more information about ListView performance.
When you have custom cells in a ListView is recommended to use CachingStrategy
ListView is a powerful view for displaying data, but it has some limitations. Scrolling performance can suffer when using custom cells, especially when they contain deeply nested view hierarchies or use certain layouts that require complex measurement.
XAML for Xamarin.Forms provides a XAML attribute for a non-existent property that corresponds to the caching strategy argument :
<ListView CachingStrategy="RecycleElement" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- ... -->
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Try this
<ListView
x:Name="list"
SelectionMode="None"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
SeparatorVisibility="None"
HasUnevenRows="True"
BackgroundColor="Transparent"
CachingStrategy="RetainElement"
>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="10" Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition Height="Auto"
/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Orientation="Horizontal" HorizontalOptions="FillAndExpand" >
<Label
Text="{Binding Note}"
HorizontalOptions="StartAndExpand"
TextColor="Black"
FontSize="Small"
FontFamily="
{StaticResource BoldFont}"
FontAttributes="Bold">
</Label>
<ImageButton
HorizontalOptions="EndAndExpand"
WidthRequest="22"
HeightRequest="22"
Padding="6"
Margin="0,0,0,0"
Clicked="btndelete"
AbsoluteLayout.LayoutBounds="0,0,1,1"
BackgroundColor="Transparent"
Source="close.png">
</ImageButton>
</StackLayout>
<StackLayout Grid.Row="1" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label
Text="{Binding
NOfQuestions}"
HorizontalOptions="StartAndExpand"
FontSize="12"
FontFamily="
{StaticResource Regular}"
TextColor="White">
</Label>
<Label
Margin="15,0,0,0"
Text="{Binding
NOfDigits}"
HorizontalOptions="CenterAndExpand"
FontSize="12"
FontFamily="
{StaticResource Regular}"
TextColor="White">
</Label>
</StackLayout>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Add a right border to a label

I'm trying to do add a right border to my label. In CSS, you can to this with a few lines of code:
label {
border-right : 2px solid #000;
}
This seems to be different in Xamarin.Forms XAML as there are no border properties on any of the elements. This is similar to what I'm trying to achieve:
Here is my code:
<ListView x:Name="listview" SeparatorVisibility="None"
HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20, 10">
<Label Text="{Binding LoremIpsum}"
HorizontalOptions="Start"/>
<Label Text="{Binding LoremIpsum1}" />
<Label Text="{Binding LoremIpsum2}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Is there any way I can add a right border to the label? I tried using a BoxView with WidthRequest = 1 and HeightRequest = 10 but it did not work. I even tried using an image but that is not good practice. Any help would be appreciated.
Use Grid Layout and BoxView to show the right border with color green and width 2
eg.
<ListView x:Name="listview" SeparatorVisibility="None"
HasUnevenRows="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<BoxView Grid.Column="0" Color="Green"/>
<StackLayout Grid.Column="1" Padding="20, 10">
<Label Text="{Binding LoremIpsum}"
HorizontalOptions="Start"/>
<Label Text="{Binding LoremIpsum1}" />
<Label Text="{Binding LoremIpsum2}" />
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Output:
As an alternate solution to using a Grid, you could also accomplish this with a StackLayout. The key here being to nest your original StackLayout inside another, with Orientation="Horizontal".
<ListView
x:Name="listview"
SeparatorVisibility="None"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
Orientation="Horizontal">
<StackLayout
Padding="20, 10"
HorizontalOptions="FillAndExpand">
<Label
Text="{Binding LoremIpsum}"
HorizontalOptions="Start"/>
<Label
Text="{Binding LoremIpsum1}" />
<Label
Text="{Binding LoremIpsum2}" />
</StackLayout>
<BoxView
WidthRequest="1"
Color="Green" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Categories

Resources