Xamarin.Forms: how to set Images to get the expected result - image

I'm looking for a good way to implement a control that looks like a ListView with 2 columns, where each column has distinct height. As I didn't found another solution, I've decided to do it through a Repeater control.
The expected result is something like this:
All the items come from the same DataSource, and this DataSource will contain between one and a dozen of items.
The items must be splitted automatically (by modulo) into the 2 columns
When the user click on the button related to the item, this will open the item's detail page
The red squares are images that must have the same height/width
I'm working on the design of the cell DataTemplate, but I didn't see how to manage the images:
The distinction between the 2 columns is given by a Grid containing 2 Columns
Then I specify the DataTemplate for each column
<ScrollView>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Col.1 -->
<tabletControls:Repeater Grid.Column="0" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
<!-- Col.2 -->
<tabletControls:Repeater Grid.Column="1" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
</Grid>
</ScrollView
But this doesn't work as expected, as the image's height/width are not the same:
I already tried to play with Aspect (AspectFill, AspectFit, Fill) or VerticalOptions/HorizontalOptions, withou any result...
Is it possible to achieve the expected result without specify an HeightRequest? Are there other options?

Related

HeightRequest is not honored if content is added below

I am trying to lock the height of a header - or basically any kind of content on the top of a page. However, once scrollable content is added below the height changes. A simple example:
<ContentPage.Content>
<StackLayout Padding="0" Margin="0" Spacing="0">
<Frame Margin="0" HeightRequest="150" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
</StackLayout>
</ContentPage.Content>
This works fine. However, adding a lot of simple label lines in a scrollview somehow changes the height of the frame.
<ContentPage.Content>
<StackLayout Padding="0" Margin="0" Spacing="0">
<Frame Margin="0" HeightRequest="150" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
<ScrollView>
<StackLayout>
<Label Text="aaa" /> <!-- Repeated 54 times however removed here for simplicity-->
</StackLayout>
</ScrollView>
</StackLayout>
</ContentPage.Content>
The results end up like this:
Why does it happen and can I do anything to avoid it? And why is the height reduced to exactly that height? Thanks!
It doesn't seem like you're limiting the height of the ScrollView. So considering you're merely doing a HeightRequest, it may change as needed to fit everything.
It's usually safer to use Grids. In this example, something like this could help you:
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Frame Grid.Row="0" Margin="0" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
<ScrollView Grid.Row="1">
<StackLayout>
<Label Text="aaa" /> <!-- Repeated 54 times however removed here for simplicity-->
</StackLayout>
</ScrollView>
</Grid>
</ContentPage.Content>

How to set all the item template data into a single view in Xamarin Carousel

I have tried to make all the items in the itemtemplate into a single view as like in the below image, how to achieve this by using Xamarin CarouselView, i am using like this
carousel = new CarouselView();
carousel.BindingContext = this;
carousel.ItemTemplate = itemTemplate;
carousel.SetBinding(CarouselView.ItemsSourceProperty, new Binding(nameof(this.Items), mode: BindingMode.OneWay));
LinearItemsLayout linearItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
linearItemsLayout.SnapPointsAlignment = SnapPointsAlignment.Start;
linearItemsLayout.SnapPointsType = SnapPointsType.Mandatory;
carousel.ItemsLayout = linearItemsLayout;
this.Children.Add(carousel,0,1);
Expected UI
The easiest way of doing something like that would be to use the Horizontal CollectionView
CollectionView can display its items in a horizontal list by setting its ItemsLayout property to HorizontalList:
When you check the documents it gives a similar example
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
Alternatively, this layout can also be accomplished by setting the ItemsLayout property to a LinearItemsLayout object, specifying the Horizontal ItemsLayoutOrientation enumeration member as the Orientation property value:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
This results in a single row list, which grows horizontally as new items are added:

xamarin how to show multiple column grid which support both andriod and iOS

I want to create a list view with four column, first two column will have text and next two column will have clickable button(image). Number of rows is not fixed- so data binding is require. Should support android and iOS. please suggest which xamarin control will be best suited for me.
Can i use data template as shown in https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/templates/data-templates/selector/
or should use Grid, Grid layout or any other.
======== Solution Applied=============
<ListView x:Name="listViewExpenses" CachingStrategy="RecycleElement" VerticalOptions="FillAndExpand" RowHeight="40">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<!--<Label x:Name="idLabel" Text="{Binding Id}"/>-->
<Label x:Name="textLabel1" Grid.Column="0" Text="{Binding Text}"/>
<!--<Button x:Name="btnEdit" Image="icon.png" HeightRequest="50" WidthRequest="50" Grid.Column="2" CommandParameter="{Binding Id}" Clicked="OnEditClicked" />-->
<StackLayout Grid.Column="1">
<Image Source="EditRed.png" VerticalOptions="Center" >
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnEditTapped"
CommandParameter="{Binding Id}"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>`enter code here`
=====================================
Thanks,
#paul
As the number of rows is not fixed but each row will look the same, I would suggest a List View with an inline data template.
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/templates/data-templates/creating/
Data templates you mentioned is required in case of different row views. For your case Grid should be sufficient. You can add rows dynamically for example like shown here
https://forums.xamarin.com/discussion/42393/need-to-add-rows-dynamically-in-a-grid
If that doesn't work you can use ListView with custom cells
https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/customizing-cell-appearance/

How to adjust my listview in ios Xamarin forms

I have a problem in my ListView on iOS. I can't adjust it to all iOS templates, ex: put HeightRequest = "855" on my iPhone 7 it already fits correctly, else on the iPhone 5 and smaller my ListView from a scrow. so I want my ListView to automatically adjust to the screen size.
<ListView x:Name="listView"
CachingStrategy="RecycleElement"
ItemsSource="{Binding FeedItems}"
HasUnevenRows="True"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1" HeightRequest="855">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout HeightRequest = "60" WidthRequest="60">
<Image x:Name="Image" Source="{Binding Image}" Scale="1.0" Aspect="AspectFill" VerticalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Grid.Column="2" Spacing="4" VerticalOptions="Center">
<Label Text="{Binding Category}" TextColor="White" FontSize="Small" LineBreakMode="NoWrap" BackgroundColor="{Binding Color_category}"/>
<Label Text="{Binding PublishDate}" TextColor="#666666" FontSize="Small" LineBreakMode="NoWrap"/>
<Label Text="{Binding Title}" TextColor="#234084" Font="Bold" FontSize="Small" LineBreakMode="WordWrap"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
To expand a little more.
HeightRequest is used when you want to define a fixed size to an element. Xamarin will make its best to fulfill with this. In the other hand when you want your size to be relative you use the VerticalOptions and HorizontalOptions. This two properties will take a LayoutOptions struct and the default value for this is Fill (without expand).
This struct has two sets of properties, the ones I call "regular"
Center
Start
End
Fll
And the ones that "expands"
CenterAndExpand
StartAndExpand
EndAndExpand
FillAndExpand
You can read more about these here.
This last one FillAndExpand will take all the available space in the orientation it's used. This is the one you should use in your ListView to make it as big as the screen
Hope this helps.-

WinRT element rendering bug

I have a small issue with rendering of some elements on a WinRT application.
The page is loaded but the elements of my listview are randomly dimmed for a few seconds. Sometimes they appear in gray and sometimes they are fine.
For information I use image for my listview items backgrounds (weight of my image = 4ko).
I also tryed to give them a fixed Width and fixed DecodePixelWith but it doesnt change anything.
Any tips for solving this issue ? screen shot example of my bug
Thanks everyone :p
This one is the datatemplate (it's a short example of my XAML code)
<DataTemplate x:Key="ListViewIntervention">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="170" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.ColumnSpan="2" NineGrid="50,50,170,50" Stretch="Fill">
<Image.Source>
<BitmapImage UriSource="ms-appx:///Assets/Shadow/ListViewUnplanned.png"
DecodePixelWidth="1200"
DecodePixelType="Physical"/>
</Image.Source>
</Image>
</Grid>
<Grid x:Name="grid_with_some_buttons>
</Grid>
</Grid>
</DataTemplate>
and there is my listview :
<ListView
Name="DataListView" Grid.Row="2"
Margin="35,10,15,0" IsSwipeEnabled="False"
ItemTemplate="{StaticResource ListViewIntervention}"
ItemsSource="{Binding InterventionsCollection}"
ScrollViewer.HorizontalScrollMode="Disabled" SelectionMode="Single">
</ListView>
Atm my listView contain 350 items.

Resources