Dynamic Horizontal List View in xamarin forms - xamarin.forms

I need to integrate the Dynamic horizontal listview in my project. I found this concept below blog on the website. But I confused this code to integrate into my project. Kindly suggest me an idea to anyone. I need this image type grid or horizontal listview( https://i.stack.imgur.com/OvJZE.png).
Mainpage.xaml.cs
public void SetupUserStack()
{
---------- issue in _itemSelectCommand in my code
cButtonList.Add(new CircleButton(_itemSelectCommand)
{ CircleSize = otherCircleSize, CircleFontSize = 35, Text = initials, BackgroundColor = Color.White, TextColor = ourBlue, BorderColor = ourBlue, BorderWidth = 1.5 });
var b2 = new Button() { Text = lname, TextColor = ourBlue };
//otherGrid.Children.Add(LargeCB, 0, 0);
otherGrid.Children.Add(cButtonList[i], 0, 0);
otherGrid.Children.Add(b2, 0, 1);
UserStack.Children.Add(otherGrid);
}
Blog I refer: horizontal-list-view-with-circular-button-styling-in-xamarin-forms

This is the another way to achieve the same thing. Xamarin forms now support the Bindable Layouts
XAML Code:
<ScrollView
Orientation="Horizontal"
HorizontalScrollBarVisibility="Default">
<StackLayout Margin="20,0,20,0"
Orientation="Horizontal"
BindableLayout.ItemsSource="{Binding LogoImages}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Image
HeightRequest="25"
Margin="0,0,5,0"
Source="{Binding logoImage}">
</Image>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
Here is more information with the example :
Bindable Layouts

Use a collectionView to create a horizontal-list would be easier and faster, for 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" />
//...your layout
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The Monkeys should be a list that in your ViewModel.
You can check the sample with MVVM structure here:collectionviewdemos
In your linking blog, he creates the grid dynamically with the users.Count and I think it hard to integrate his code to MVVM structure.

Related

problem with image inside grid inside list view xamarin forms

Im facing a real strange problem, I am developing a xamarin forms app, let me show you the problem:
So I have this listview with items.
click here to see the list
Then i tapped an item, and this fires a Navigation.PushAsync to this page
Then, when i go back to the list, The image size has changed, watch this image
I have tried change the list view to a collection view but the problem is the same. Im deploying this app on android
This is the xaml code
<StackLayout Margin="10,0,10,0">
<ListView x:Name="lvResultadoBusqueda" SelectionMode="Single" ItemSelected="lvResultadoBusqueda_ItemSelected" ItemTapped="lvResultadoBusqueda_ItemTapped" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="#FFFFFF" Padding="0,5,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="15"/>
<RowDefinition Height="15"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Frame Padding="0" OutlineColor="#E4E7EC" HasShadow="True" Grid.RowSpan="4" Grid.Column="0">
<Image Source="{Binding urlImagenPortada}" Aspect="Fill"></Image>
</Frame>
<Label Text="{Binding titulo}" Grid.Row="0" Grid.Column="1" FontSize="14" TextColor="#000000" FontAttributes="Bold"></Label>
<Label Text="{Binding autores}" FontSize="12" Grid.Row="1" Grid.Column="1" TextColor="#868b8f"></Label>
<StackLayout Grid.Row="2" Grid.Column="1" Orientation="Horizontal" Spacing="5" BackgroundColor="Transparent">
<Label Text="{Binding valoracionExacta}" FontSize="12" TextColor="#868b8f" BackgroundColor="Transparent"></Label>
<Image Source="star_blue.png" WidthRequest="10" HeightRequest="10" Margin="0,4,0,0"></Image>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
and this is the c# code
private void lvResultadoBusqueda_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
ListView listView = (ListView)sender;
listView.SelectedItem = null;
}
private void lvResultadoBusqueda_ItemTapped(object sender, ItemTappedEventArgs e)
{
var item = e.Item as BuscarCatalogoVM;
if (item != null)
{
Navigation.PushAsync(new Catalogo.DetalleCatalogo(item.idRepositorioDigital));
}
}
I really hope you can help me, thanks !
UPDATE 1: I tried what Ryan told me:
<Frame Padding="0" OutlineColor="#E4E7EC" HasShadow="True" Grid.RowSpan="4" Grid.Column="0">
<Image Source="{Binding urlImagenPortada}" Aspect="AspectFit" HorizontalOptions="FillAndExpand"></Image>
</Frame>
And this is the screenshot :C
UPDATE 2: With the FFImageLoading plugin, I dont have that problem, it works great, but it seems that the DownsampleToViewSize property is not working, when I set it to true, the image does not fit , So I have to put it false and add Aspect="Fill" or Aspect="AspectFill", but this solutions cuts the image of the book
Friend from Peru
Try using Xamarin.FFImageLoading.Forms
https://askxammy.com/optimizing-handling-images-with-ffimageloading/
Also
I share this link for the management of transitions.
https://geeks.ms/jsuarez/2019/05/29/xamarin-forms-ui-challenge-art-news-transiciones-entre-paginas/
You can share the code in git and I'm debugging the project to try to help you.
<Frame Padding="0" OutlineColor="#E4E7EC" HasShadow="True" Grid.RowSpan="4" Grid.Column="0">
<Image Source="{Binding urlImagenPortada}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"></Image>
</Frame>
add HorizontalOptions="FillAndExpand" and VerticalOptions="FillAndExpand"

Xamarin Forms Prism DialogService show behind ModalNavigation

I am using a custom DialogService, the problem I have is that I first show a page as a modal and when sending to display the DialogPage it is apparently not shown but it really is behind the model page.
Invocation of the modal page
await _navigationService.NavigateAsync("ProfilePage", useModalNavigation: true);
Xaml CustomDialog
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
prism:DialogLayout.LayoutBounds="0.5, 0.5, -1, -1"
prism:DialogLayout.RelativeWidthRequest="0.60"
BackgroundColor="White"
x:Class="ComedorIndustrial.Prism.Views.MessageDialog">
<Grid Padding="30,60">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="iconoError.png" />
<Label Text="{Binding Title}" HorizontalTextAlignment="Center" TextColor="#ee3837" Grid.Row="1" Style="{StaticResource RobotoBold}" FontSize="30"/>
<Label Text="{Binding Message}" HorizontalTextAlignment="Center" TextColor="#bdbcc2" Grid.Row="2" FontSize="14" />
<Button Text="Volver a intentar"
Command="{Binding CloseCommand}"
BackgroundColor="#ee3837" BorderRadius ="25" TextColor="White" HorizontalOptions="FillAndExpand" Opacity="1" FontSize="12" Margin="0,15,0,0"
Grid.Row="3"/>
</Grid>
</ContentView>
Custom dialog invocation
public static void ShowAlert(this IDialogService dialogService, string title, string message)
{
var parameters = new DialogParameters
{
{ "title", title },
{ "message", message }
};
dialogService.ShowDialog("MessageDialog", parameters);
}
EDIT:
I have solved it!
Add the plugin: Prism.Plugin.Popups
And then add the following line of code in App.xaml.cs: containerRegistry.RegisterPopupDialogService();
The documentation is on the following page:
popups.prismplugins.com
Regards!
What you've described is a known bug in Prism 7.2. This issue is fixed in Prism 8, or as you've noted you can simply use the Prism.Plugin.Popups to use the PopupPage variant of the service.

Can you define RowDefinition in style xamarin forms

I have the following
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"></RowDefinition>
<RowDefinition Height="7.5*"></RowDefinition>
</Grid.RowDefinitions>
and I would like to define the Height in a Style or in a variable in the app.xaml.
<Grid.RowDefinitions>
<RowDefinition Height="{StaticResource myHeight}"></RowDefinition>
<RowDefinition Height="{StaticResource myHeight2}"></RowDefinition>
</Grid.RowDefinitions>
Is this possible? I have tried but I get an error.
The reason I want to achieve this is that on small devices I need to change the row height.
I would appreciate any tips or suggestions.
You can bind a model to ContentPage , then Grid can use binded data by model and row height can be setted by model data (contain row height paramaters).
For example , create a sample ViewModel(RowHeightClass) as follow :
using Xamarin.Essentials;
public class RowHeightClass
{
public GridLength rowFirstHeight { set; get; }
public GridLength rowSecondHeight { set; get; }
public RowHeightClass()
{
// here can add code set by device screen
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
double screenheight = mainDisplayInfo.Height;
rowFirstHeight = new GridLength(DeviceDisplay * 0.2);
rowSecondHeight = new GridLength(DeviceDisplay * 0.4);
}
}
Binding it in ContentPage :
RowHeightClass rowHeightClass = new RowHeightClass();
BindingContext = rowHeightClass;
Used in XAML :
<Grid VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding rowFirstHeight}" />
<RowDefinition Height="{Binding rowSecondHeight}" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BoxView Grid.Row="0"
Grid.Column="0"
BackgroundColor="Blue" />
<BoxView Grid.Row="1"
Grid.Column="0"
BackgroundColor="Red" />
<Button Grid.Row="2"
Grid.Column="0"
BackgroundColor="Yellow"
Clicked="Button_Clicked" />
</Grid>
Note : You can modify the constructor method of RowHeightClass to add method to set needed height by the size of device screen .
==================================Update=====================================
Using StaticResource also can set the heigh of row . Add a Resources for Grid or Application as follow :
<Grid VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.Resources>
<ResourceDictionary>
<x:Double x:Key="SmallScreenRowheight">200</x:Double>
<x:Double x:Key="LargeScreenRowheight">400</x:Double>
</ResourceDictionary>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="{StaticResource SmallScreenRowheight}" />
<RowDefinition Height="{StaticResource LargeScreenRowheight}" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<BoxView Grid.Row="0"
Grid.Column="0"
BackgroundColor="Blue" />
<BoxView Grid.Row="1"
Grid.Column="0"
BackgroundColor="Red" />
<Button Grid.Row="2"
Grid.Column="0"
BackgroundColor="Yellow"
Clicked="Button_Clicked" />
</Grid>

Xamarin Forms : Drawing a line under listview

Dears,
I need to draw a Blue line under listview like the following picture:
My code is:
<StackLayout>
<Image
Source="blue_holo_circle.png">
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
items inside listview like profile,name,time,like etc>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
I know the code for drawing a line using BoxView :
<BoxView
VerticalOptions="Fill"
HorizontalOptions="Center"
WidthRequest="1"
Color="Blue"/>
But I don't know where I need to add the code for the line, I try to add before listview, but the line is not coming under the list.
Anybody suggest a solution for drawing a line under the list items(listview)?
Thanks in advance....
<ListView ItemsSource="{Binding Items}"
CachingStrategy="RecycleElement"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20">
<StackLayout Padding="5" BackgroundColor="LimeGreen">
<Label Text="{Binding .}"
Style="{DynamicResource ListItemTextStyle}" />
<Label Text="{Binding .}"
Style="{DynamicResource ListItemDetailTextStyle}"/>
</StackLayout>
<BoxView
VerticalOptions="Fill"
HorizontalOptions="Start"
WidthRequest="1"
Color="Blue"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
// Code Behind
public partial class ListViewPage1 : ContentPage
{
public ObservableCollection<string> Items { get; set; }
public ListViewPage1()
{
InitializeComponent();
Items = new ObservableCollection<string>
{
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"
};
BindingContext = this;
}
}
Try like this....
Better use Grid to your requirement , it will be very useful and easy to understand the design we are up to.
This Resolved my Problem.
<StackLayout>
<BoxView HeightRequest="1" VerticalOptions="Fill" BackgroundColor="White" />
</StackLayout>
I used it in the Grid.
<Grid BackgroundColor="#0073E0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout Grid.Column="1" Grid.Row="1">
<BoxView HeightRequest="1" VerticalOptions="Fill" BackgroundColor="White"/>
</StackLayout>
</Grid>

Xamarin.Forms: Getting the position from a tapped Image inside a Listview

I want to save the position of the tapped Image inside my ListView. It's a Tapped event so it doesn't count as ItemSelected.
It's a simple ListView and each element has a "star" image to mark as favourite. It could work browse the ListView and get the positions where the Image is the "filled star" on the OnDisappearing() saving them on an array for example.
ListView Structure:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0"/>
<Image Grid.Row="0" Grid.Column="1"/>
<Image x:Name="imageFavourite"
Source="starBorder.png"
Scale="0.5"
HorizontalOptions="Center"
VerticalOptions="Center"
Grid.Row="0" Grid.Column="2">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="imageFavourite_Tapped"
NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
</Image>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
How can I do this?
Here is an example of how to get the command parameters working with casting the binding instead of the way that you're doing it.
Here is the image xaml set up:
<Image x:Name="DeleteImage"
Source="ic_delete.png"
Margin="25,0,0,0">
<Image.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding .}" Tapped="DeleItem" NumberOfTapsRequired="1"/>
</Image.GestureRecognizers>
</Image>
Here is the C# backend for the tap gesture recognizer (note: this is using a TappedEventArgs not EventArgs!):
async void DeleItem(object sender, TappedEventArgs args)
{
var row = (YOUR-OBJECT-CAST)args.Parameter;
System.Diagnostics.Debug.Write($"Row clicked: (your object) {row.ID}");
}

Resources