How to show group and grouped items within a frame Xamarin.Forms - xamarin

Has anyone implanted something like the following, that could be of relevance to me? How can I put a frame that encompasses both the group and the items in the photo:
click to enlarge

I have a dirty but simple way:
When I make same forms I use ListView without grouping and ViewCell with RepeaterView. You need remember that it is not the best perfomance way.

If you want to design the UI like the screenshot your provided, using frame to crop image, you can take a look:
<CollectionView IsGrouped="true" ItemsSource="{Binding Animals}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Frame Padding="0"
Grid.RowSpan="2"
BorderColor="Black"
CornerRadius="50"
HeightRequest="40"
HorizontalOptions="Center"
IsClippedToBounds="True"
WidthRequest="40">
<Image
Aspect="AspectFill"
HeightRequest="100"
Source="{Binding ImageUrl}"
WidthRequest="100" />
</Frame>
<Label
Grid.Column="1"
FontAttributes="Bold"
Text="{Binding Name}" />
<Label
Grid.Row="1"
Grid.Column="1"
FontAttributes="Italic"
Text="{Binding Location}"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label
BackgroundColor="LightGray"
FontAttributes="Bold"
FontSize="Large"
Text="{Binding Name}" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>
About viewmodel class, you can take a look Xamarin.Forms CollectionView Grouping

Related

Xamarin Forms 2.X - ListView with Grid how to call API for each Row that is inserted into my grid rows

I have the following Xamarin forms grid.
<ListView x:Name="liewViewData" ItemsSource="{Binding InfoList}" ItemAppearing="OnItemApprearing" ItemSelected="OnItemSelected" RowHeight="{Binding ListViewRowHeight}">
<ListView.Header>
<StackLayout Padding="10,5,0,5" BackgroundColor="#cccccc">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="" VerticalTextAlignment="Center" HorizontalTextAlignment="Start" FontSize="Small" />
<Label Grid.Column="1" Text="Demo" VerticalTextAlignment="Center" FontSize="Small" />
</Grid>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Image Source="danger.png" Grid.Column="0" BackgroundColor="Transparent" HorizontalOptions="Center" VerticalOptions="Center"></Image>
<Label Grid.Column="1" Text="{Binding Name}" VerticalTextAlignment="Center" FontSize="Small" />
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
What I need is that on the ItemAppearing event for each grid row added I call an API and update the row data such as the image etc.
Any clue on how to do this?
You need to data bind the image, implement OnPropertyChanged for that field and assign value to it in the event that you mention. Not sure which part you were missing, but as simple as that.

CollectionView Xamarin grid view sizing

I am working with a collectionview using GridItemsLayout orientation=“Vertical” Span=“2”.
When I click on a button that expands the lower part of my grid item. Currently only by using ItemSizingStrategy.MeasureAllItems I am able to get the lower part to expand. I was wondering if there is a way of controlling the item positioning on the image so the images always align and only the lower half expands evenly.
I am aware each item has its own layout, but this looks messy. I’ve read the documentation mention this type of sizing.
<ContentPage.Content>
<StackLayout>
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True"
ItemSizingStrategy="MeasureAllItems">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
/>
<Button Text=" More"
FontSize="16"
Clicked="OpenButton_Clicked"/>
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<!--TEMPLATING-->
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="viewmodels:ShareViewModel">
<Grid Padding="5" Margin="1,0,1,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton x:Name="image"
Source="{Binding ImageLink}"
WidthRequest="150"
Clicked="FullImageView"
Grid.ColumnSpan="2"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label FontSize="16"
Text="{Binding Name}"
Grid.Row="1"
Grid.Column="0"/>
<Label x:Name="label_more"
Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label
Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
<ImageButton IsVisible="{Binding TVNImageSet}"
Command="{Binding BindingContext.ToggleTVNCommand, Source={x:Reference Name=sharepage}}"
CommandParameter="{Binding .}"
Source="addresscard.png"
Grid.Row="2"
Grid.Column="1">
</ImageButton>
<!--Lower Section if the card is tapped (EXPAND)-->
<StackLayout
IsVisible="{Binding TVNVisible}"
Grid.Row="3"
Grid.ColumnSpan="2">
<StackLayout Orientation="Horizontal"
IsVisible="{Binding PhoneVisible}"
ClassId="{Binding Phone}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
NumberOfTapsRequired="1"
/>
</StackLayout.GestureRecognizers>
<Image Source="call.png"
WidthRequest="15"/>
<Label
FontSize="12"
Text="{Binding Phone}" />
</StackLayout>
<Label
FontSize="12"
Text="{Binding Address}"
IsVisible="{Binding AddressVisible}">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" NumberOfTapsRequired="1"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
All BindingContext.ToggleTVNCommand does is set TVNVisible to true which shows the lower half the "expanding potion". I don't need to use collection view if there is an easier way fo displaying this data, but CollectionVView seemed like the best choice for the layout and item source I wanted.
After digging around GitHub forums on bugs and updates for Xamarin, someone mentioned to just work with SyncFusion's sfListview the membership is not that bad and my company is willing to pay for it if it makes working with Xamarin easier.
That wasn't the solution I was hoping for, but it works and their customer support is great.
below is the reference
https://help.syncfusion.com/xamarin/listview/working-with-sflistview

Xamarin Forms CollectionView Horizontal items overlapping on ios

We've got an simple collection view for horizontal items. See code below.
<CollectionView ItemsSource="{Binding Items}" ItemsLayout="HorizontalList" ItemSizingStrategy="MeasureFirstItem" HorizontalOptions="StartAndExpand" VerticalOptions="Start" Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="Item_Tapped" CommandParameter="{Binding .}"></TapGestureRecognizer>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Image
Source="{Binding ImageUrl}"
HorizontalOptions="Fill"
VerticalOptions="Fill"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label
HorizontalOptions="Center"
Grid.Row="1"
Text="{Binding Title}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
On android this works great and I've got items stand neatly next to each other. On iOS the items are overlapping each other. Cannot find why this doesn't work on iOS.

AutoScale Label Xamarin

I am working on an app that displays results from a RSS feed. I am trying to show the Title and the Date in the same row of a Stacklayout.
Xaml Code:
StackLayout>
<Label Text="60 Second Sports" FontAttributes="Bold" HorizontalOptions="Center"/>
<ListView x:Name="mainArticleRssList" IsPullToRefreshEnabled="True" Refreshing="ListItems_Refreshing" ItemTapped="RssList_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,0,15,0">
<Label Text="{Binding Title}"
LineBreakMode="WordWrap"
MaxLines="2"/>
<Label Text="{Binding PublishedDate}"
LineBreakMode="WordWrap"
MaxLines="1"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<controls:AdMobView />
</StackLayout>
Here is what it looks like:
What I Expect:
I want the Title to auto scale to fit in the same row as the date. Is it possible to set a width for the entire row and then have the two labels fit inside of the row?
Other fruits of a few hours of googling:
Here are some of the links I found, but some are old and not sure if they work.
This one is old Auto Scale Text Size
This one didn't work Auto-scaling label fontsize in Xamarin
I also found a couple Nuget packages, but i don't think i need to do that.
https://baskren.github.io/Forms9Patch/
https://forums.xamarin.com/discussion/43468/autosize-font-label
Use Grid Layout inside stack layout to achive it
<ListView x:Name="mainArticleRssList" IsPullToRefreshEnabled="True" HasUnevenRows="True" Refreshing="ListItems_Refreshing" ItemTapped="RssList_ItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,0,15,0">
<Grid x:Name="grd">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Title}"
LineBreakMode="WordWrap"
MaxLines="2"/>
<Label Text="{Binding PublishedDate}" Grid.Column="1"
LineBreakMode="WordWrap"
MaxLines="1"/>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Use this code and it will work for you.
Is that your needs like this screenshot?
You can use Grid to achieved that.
<ContentPage.Content>
<StackLayout>
<Label Text="Xamarin.Forms native cell" HorizontalTextAlignment="Center" />
<ListView x:Name="listView" CachingStrategy="RecycleElement"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Title}" Grid.Row="0" Grid.Column="0"
LineBreakMode="TailTruncation"
MaxLines="2" />
<Label Text="{Binding PublishedDate}" Grid.Row="0" Grid.Column="1"
LineBreakMode="WordWrap"
MaxLines="1"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
If title is too long, you can setLineBreakMode="TailTruncation" it will automatically truncate when the label reaches the end of the container.

WP7 ListBox Scrolling Not Working

I have the following XAML markup in a WP7 UserControl. My problem is that when my ListBox has more items than will fit on a page it will not scroll properly. I can scroll the list by panning upwards with my finger but as soon as I remove my finger it jumps back to the top of the list (if the list is very long then the scrolling will not even work to this limited extent).
I have tried numerous different layouts with no success e.g. Wrapping ListBox in ScrollViewer, utilising StackPanel instead of Grid, removing the WrapPanel and replacing it with a grid.
Other similar questions suggested removing StackPanel (which I did but made no difference) or using ScrollViewer (which did not work).
The Page that hosts the UserControl uses a GestureListener - I removed that and it still made no difference.
<Grid x:Name="LayoutRoot"
Background="SteelBlue">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--<TextBlock Grid.Row="0"
Text="Search"
Style="{StaticResource PhoneTextTitle2Style}" />-->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Search Type"
Grid.Column="0"
VerticalAlignment="Center" />
<RadioButton Content="RMB/RSD"
Grid.Column="1"
IsChecked="{Binding Path=SearchType, Converter={StaticResource enumBooleanConverter}, ConverterParameter=RMB, Mode=TwoWay}" />
<RadioButton Content="Name"
Grid.Column="2"
IsChecked="{Binding Path=SearchType, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Name, Mode=TwoWay}" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Search Term"
Grid.Column="0"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Text="{Binding SearchTerm, Mode=TwoWay}"
InputScope="{Binding SearchTermInputScope}">
<i:Interaction.Behaviors>
<b:SelectAllOnFocusBehavior />
</i:Interaction.Behaviors>
</TextBox>
</Grid>
<Button Grid.Row="2"
Content="Find"
cmd:ButtonBaseExtensions.Command="{Binding FindDeliveryPointsCommand}" />
<ListBox Grid.Row="3"
ItemsSource="{Binding SearchResults}"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:WrapPanel Orientation="Horizontal"
Width="480"
Background="{Binding RMB, Converter={StaticResource alternateColorConverter}}">
<TextBlock Text="{Binding RMB}"
FontSize="26"
Foreground="Navy"
Padding="5"
Width="60" />
<TextBlock Text="{Binding HouseholdName}"
FontSize="26"
Foreground="Navy"
Padding="5"
Width="420" />
<TextBlock Text="{Binding StreetWithRRN}"
FontSize="26"
Foreground="Navy"
Padding="5" />
<TextBlock Text="{Binding Street.Locality.Name}"
FontSize="26"
Foreground="Navy"
Padding="5" />
</toolkit:WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Specify ListBox.Height - something like Height="200". As it is now, ListBox expands automatically to accomodate all loaded items and it grows out of the screen. As a result you get large page with no scroller.
When you add ListBox.Height, the ListBox area won't grow. Instead ListBox ScrollViewer will be activated and you'll get the effect you need.
I use databinding when the ListBox's Height changed depending on the other controls on the page.
<StackPanel x:Name="ContentPanel" Grid.Row="1">
<ListBox x:Name="LstSample" Height="{Binding ElementName=ContentPanel, Path=ActualHeight}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImagePath}" Stretch="None"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" FontSize="45"/>
<TextBlock Text="{Binding Group}" FontSize="25"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>

Resources