How to scale font and container's height in Xamarin.Forms - xamarin.forms

I have problem with properly scaling height of containers and font size in Xamarin.Forms.
1) The first problem is that I need to set static height in one of my containers but it looks different on different devices. I don't know exactly but suppose that problem can be caused by screen density. Should I scale height of my container somehow or Xamarin.Forms should handle this for me?
2) The second problem is that I need to set proper cross-platform font. Is there a way to Xamarin.Forms handle it for me or need I use Device.RuntimePlatform property to set this? Also as said here: https://learn.microsoft.com/pl-pl/xamarin/xamarin-forms/user-interface/text/fonts - named font sizes are not acceptable solution. For iPod I need to use micro, but on android the text is barely visible.
On emulator there are many weird things happen, topbar is way out of scale and entire look is zoomed. Is this my fault or maybe Xamarin is not such universal platform I thought?
Here is the code of my page:
<StackLayout>
<SearchBar
VerticalOptions="Start"
TextChanged="SearchBar_OnTextChanged"
PlaceholderColor="#C0C0C0"></SearchBar>
<ListView
BackgroundColor="#f2f2f2"
VerticalOptions="Center"
ItemTapped="SelectProcedure"
CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding Name}"
TextColor="Black"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout
BackgroundColor="White"
HeightRequest="80"
HorizontalOptions="FillAndExpand"
VerticalOptions="EndAndExpand">
<Grid
Padding="10,5,10,5"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
Grid.Row="0"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalTextAlignment="Center"
HorizontalOptions="Center"
TextColor="Black"/>
<telerikInput:RadButton
Grid.Column="1"
Grid.Row="0"
Padding="5,0,5,0"
ImageSource="plus.png"/>
</Grid>
</StackLayout>
</StackLayout>
And here are the screenshots for two devices I have and emulator:
Android 8.1
iPod touch 6
Android 8.1 (emulator)

Solution: You can set the HeightRequest grid as the percentage of screen height (for example 10%) .
<StackLayout
BackgroundColor="White"
HeightRequest="{Binding stackHeight}"
HorizontalOptions="FillAndExpand"
VerticalOptions="EndAndExpand">
in Share Project App.xaml.cs
public static double ScreenWidth;
public static double ScreenHeight;
in Android MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental", "CollectionView_Experimental");
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
App.ScreenWidth = Resources.DisplayMetrics.WidthPixels/Resources.DisplayMetrics.Density;
App.ScreenHeight =Resources.DisplayMetrics.HeightPixels/Resources.DisplayMetrics.Density;
LoadApplication(new App());
}
in iOS
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
//...
App.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;
App.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
//...
}
in Code Behind or ViewModel
public double stackHeight { get; private set; }
//...
if(Device.RuntimePlatform=="iOS")
{
stackHeight= App.ScreenHeight/5.0;
}
else
{
stackHeight= App.ScreenHeight/20.0;
}
And for Custom Font in Xamarin.Forms , you can check https://xamarinhelp.com/custom-fonts-xamarin-forms/

Related

Xamarin ViewCell subclass getting error in run time. "ViewCell Must Have a View"?

I am getting this runtime error saying that the CellView needs a View. I have not found anything on this so far, here on StackOverflow or on google, so I am in the total dark about what needs to be fixed.
I need to set up a list view with 2 sections. the first one is for the bikes that are in the database and the other section is for the ones that we detected but are not saved in the DB yet.
Both sections use the same UI (cell) and so I need to be able to have a sliding button (ContextAction MenuItem) in the first section and for the second section this action needs to be disabled/removed.
If it's not possible then I would need to have the action for the second section "Add" instead of "Forget".
This is why I created a subclass.
this is my code.
(edit: corections)
---- .xaml file ----
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EGrid18.Components.BikeSelectionCell"
x:Name="ThisCell">
<ViewCell.View>
<StackLayout>
<Grid ColumnSpacing="10"
BindingContext="{x:Reference ThisCell}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding BikeName}"
StyleClass="bikecellname"
Grid.Row="0"
Grid.Column="0"
VerticalOptions="Center"
HorizontalOptions="StartAndExpand"/>
<Image Source="{Binding Image}"
HeightRequest="16"
WidthRequest="16"
VerticalOptions="Center"
Aspect="AspectFit"
Grid.Column="1"
Grid.Row="0"/>
<Label Text="{Binding Distence, StringFormat='{0:F2} M'}"
Grid.Row="0"
Grid.Column="2"
VerticalOptions="Center"/>
</Grid>
</StackLayout>
</ViewCell.View>
</ViewCell>
---- .cs file ----
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace EGrid18.Components
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class BikeSelectionCell : ViewCell
{
public static BindableProperty BikeNameProperty =
BindableProperty.Create(nameof(BikeName), typeof(string), typeof(BikeSelectionCell), string.Empty);
public string BikeName
{
get => (string)GetValue(BikeNameProperty);
set => SetValue(BikeNameProperty, value);
}
public static BindableProperty ImageProperty =
BindableProperty.Create(nameof(Image), typeof(string), typeof(BikeSelectionCell), string.Empty);
public string Image
{
get => (string)GetValue(ImageProperty);
set => SetValue(ImageProperty, value);
}
public static BindableProperty DistenceProperty =
BindableProperty.Create(nameof(Distence), typeof(double), typeof(BikeSelectionCell), 0.0);
public double Distence
{
get => (double)GetValue(DistenceProperty);
set => SetValue(DistenceProperty, value);
}
public static readonly BindableProperty ForgetCommandProperty =
BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(BikeSelectionCell), null);
public ICommand ForgetCommand
{
get { return (ICommand)GetValue(ForgetCommandProperty); }
set { SetValue(ForgetCommandProperty, value); }
}
public Command OnForget => new Command(() => Execute(ForgetCommand));
// Helper method for invoking commands safely
public static void Execute(ICommand command)
{
if (command == null) return;
if (command.CanExecute(null))
{
command.Execute(null);
}
}
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if(propertyName == nameof(Image))
{
this.ContextActions.Clear();
if (Image != "unknown")
{
this.ContextActions.Add(new MenuItem()
{
Text = "Forget",
Command = ForgetCommand,
CommandParameter = this
});
}
}
}
}
}
--- the .xaml file that consumes the CellView subclass ---
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:EGrid18.ViewModels"
xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
xmlns:components="clr-namespace:EGrid18.Components"
iOS:Page.UseSafeArea="True"
x:Class="EGrid18.Views.BikeSelectionPage"
Title="Bike Selection List">
<ContentPage.Resources>
<ResourceDictionary>
<vm:BikeListViewModel x:Key="vm"/>
<StyleSheet Source="/CSS/Styles.css"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem x:Name="ScanButton" Text="Scan"
Command="{Binding Source={StaticResource vm}, Path=OnScanCommand}"
CommandParameter="{Binding Source={StaticResource vm}, Path=IsScanning}" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout Margin="8,8,8,8">
<Label Text="Bike Selection Page"
StyleClass="titlelabel"/>
<ListView x:Name="ListView"
BindingContext="{StaticResource vm}"
StyleClass="listview"
ItemsSource="{Binding BikeList}"
IsGroupingEnabled="True"
SelectedItem="{Binding SelectedBike}"
Margin="8,8,8,8">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Heading}"
VerticalOptions="Center"
Margin="8,8,8,8"/>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<components:BikeSelectionCell
BikeName="{Binding Name}"
Image="{Binding Image}"
Distence="{Binding Distence}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
A ViewCell is not a View - it isn't part of View heirarchy. It is a "wrapper" that is needed by ListView, around each item.
Personally, I never create subclasses of ViewCell, though that can be done.
IMHO, Its more straightforward to make a custom View, then wrap that in <ViewCell> to use with ListView.
As a View, you can inherit from any view class. If you don't know what else to use, inherit from ContentView. (Or from StackLayout, if need to add multiple children views.) In your case, your View is a StackLayout.
public partial class BikeSelectionView : StackLayout
... // All the lines of code you have in BikeSelectionCell go here.
xaml:
<StackLayout ... x:Name="ThisCell">
<Grid ColumnSpacing="10" ...>
... All the remaining lines of code from your xaml ...
</StackLayout>
Usage inside ListView's ItemTemplate:
<DataTemplate>
<ViewCell>
<components:BikeSelectionView
BikeName="{Binding Name}"
Image="{Binding Image}"
Distence="{Binding Distence}"/>
</ViewCell>
</DataTemplate>
One advantage of this approach is if you switch from ListView to CollectionView (which does not use ViewCells), you can still use the custom class:
<CollectionView.ItemTemplate>
<DataTemplate>
<components:BikeSelectionView ... />
</DataTemplate>
</CollectionView.ItemTemplate>
The error was coming from a missing constructor that needed to initialize the Component.
public BikeSelectionCell()
{
InitializeComponent();
}
In the end I used the suggestion ToolmakerSteve. I also used a custom DataTemplateSelector to set specifics DataTemplate for the 2 different sections
I am setting this as the answer for any one looking for this problem as the problem was really the missing call to InitializeComponent();

How to implement a UWP Custom Renderer in Xamarin-Forms using FFImageLoading

I cant find a good example about use of FFImageLoading in a UWP custom renderer for xamarin forms, good example sites use to focus in android and ios only. My main issue is how to use this Image Class in the UWP resource, CachedImage should be used in PCL project if i understand correctly. So how i should continue here? The advance use of ImageService does not detail this. I probably dont understand something. thanks in advance.
This is my View Cell in PCL:
<ViewCell>
<Grid RowSpacing="0" Padding="5,1,10,1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="32"></RowDefinition>
<RowDefinition Height="32"></RowDefinition>
</Grid.RowDefinitions>
<ffimageloading:CachedImage Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Source="{Binding MyViewModel.Image}" Aspect="AspectFit" VerticalOptions="Center" LoadingPlaceholder = "resource://MyProject.Resources.loading.png" />
<Label Grid.Column="1" Grid.Row="0" Text="{Binding MyViewModel.Name}" FontSize="16" TextColor="Red" FontAttributes="Bold" VerticalOptions="End"></Label>
<Label Grid.Column="1" Grid.Row="1" Text="{Binding MyViewModel.Serie}" FontSize="11" TextColor="Gray" FontAttributes="Italic" VerticalOptions="Start"></Label>
<ffimageloading:CachedImage x:Name="check" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" Source="{Binding MyViewModel.Own, Converter={StaticResource BoolToOwnImageSourceConverter}}}" Aspect="AspectFit" VerticalOptions="Center">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnCheckTapped"
Command="{Binding ChangeOwnCommand}"
CommandParameter="{Binding .}"/>
</Image.GestureRecognizers>
</ffimageloading:CachedImage>
</Grid>
<ViewCell.ContextActions>
<MenuItem Clicked="OnOwned" CommandParameter="{Binding .}" Text="Got it!" />
<MenuItem Clicked="OnNotOwned" CommandParameter="{Binding .}" Text="Not Yet" IsDestructive="True" />
</ViewCell.ContextActions>
Image source come from a image url stored in my view model
My main issue is how to use this Image Class in the UWP resource
If you want to custom image renderer. You could expand an attribute for xamarin image.
public class CustomImage : Image
{
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(CustomImage),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
}
And you could invoke LoadUrl to set image for native control in the custom image render.
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
var customImage = (CustomImage)Element;
if (Control == null)
{
SetNativeControl(new Windows.UI.Xaml.Controls.Image());
}
if (e.OldElement != null)
{
}
if (e.NewElement != null)
{
if (!string.IsNullOrEmpty(customImage.Uri))
{
ImageService.Instance.LoadUrl(customImage.Uri).FadeAnimation(true).Into(Control);
}
else
{
// do some stuff
}
}
}

Xamarin Forms - Prism bound properties - Rendering issue

Git: https://github.com/jimmyt1988/Test
I'm running on desktop windows 10 pc on UWP Local device "emulator"
I have a deep integer property in my view model that gets incremented by a button command.
When i do, the number disapears from the screen, and then if i resize my application, it will render correctly again.
What's happening?
It seems to work on the Android emulator.
Code
public DelegateCommand<FoodGroupModel> SubtractFromAmountEatenCommand { get; private set; }
...
SubtractFromAmountEatenCommand = new DelegateCommand<FoodGroupModel>((foodGroup) => SubtractFromAmountEaten(foodGroup));
...
public void SubtractFromAmountEaten(FoodGroupModel foodGroup)
{
if(foodGroup.AmountEaten != 0)
{
foodGroup.AmountEaten--;
}
}
...
public class FoodGroupModel : BindableBase
{
private int _amountEaten;
public int AmountEaten
{
get { return _amountEaten; }
set { SetProperty(ref _amountEaten, value); }
}
}
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="...Views.MealPage">
<StackLayout>
<Label Text="{Binding Meal.Number}"/>
<ListView x:Name="FoodGroupsListView" ItemsSource="{Binding Meal.FoodGroups}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" TextColor="#bababa" Text="Group"></Label>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Title}" />
<Label Grid.Row="0" Grid.Column="2" TextColor="#bababa" Text="Qty"></Label>
<Label Grid.Row="0" Grid.Column="3" Text="{Binding AmountEaten}" />
<Button Grid.Row="0" Grid.Column="4"
Command="{Binding Source={x:Reference FoodGroupsListView}, Path=BindingContext.UndoAmountEatenByOneCommand}"
CommandParameter="{Binding}"
Text="✖"></Button>
<Button Grid.Row="0" Grid.Column="5"
Command="{Binding Source={x:Reference FoodGroupsListView}, Path=BindingContext.SubtractFromAmountEatenCommand}"
CommandParameter="{Binding}"
Text="✔"></Button>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
When i do, the number disapears from the screen, and then if i resize my application, it will render correctly again.
You might run into an issue: The changed notification of property binding won't work well(May be related to rerender) inside Xamarin ListView, Please report it in here: Bugzilla
In Windows runtime platform(Win/WP 8.1 & UWP), we have to use a workaround to temporarily avoid this:
private void RefreashFoodGroupModel()
{
if (Device.OS == TargetPlatform.Windows || Device.OS == TargetPlatform.WinPhone)
{
//var index = Meal.FoodGroups.IndexOf(foodGroup);
//Meal.FoodGroups.RemoveAt(index);
//Meal.FoodGroups.Insert(index, foodGroup);
var t = Meal.FoodGroups;
Meal.FoodGroups = new System.Collections.ObjectModel.ObservableCollection<FoodGroupModel>();
foreach (var item in t)
{
Meal.FoodGroups.Add(item);
}
}
}
Call the above method to refresh data after data change:
public void SubtractFromAmountEaten(FoodGroupModel foodGroup)
{
if(foodGroup.AmountEaten != 0)
{
foodGroup.AmountEaten--;
RefreashFoodGroupModel();
}
}
public void UndoAmountEatenByOne(FoodGroupModel foodGroup)
{
if (foodGroup.AmountEaten != foodGroup.Quantity)
{
foodGroup.AmountEaten++;
RefreashFoodGroupModel();
}
}
This workaround will cause the refresh of ListView items.

Google Material Design Entry in Xamarin Forms

How to achieve a google material design entry / input in Xamarin.Forms (so no renderers, etc), even without the animation of the bottom label ?
Below code is a Xamarin.Forms google material design like entry approach. Total xaml + a little coding :)
Step1: Create a class in PCL project
public class CustomEntry : Entry
{
}
Step2: Create a control template in App.xaml
<ControlTemplate x:Key="MyControlTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:CustomEntry x:Name="myEntry" Text="{TemplateBinding Text, Mode=TwoWay}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Start" IsPassword="{TemplateBinding IsPassword}" MinimumHeightRequest="25"/>
<BoxView Grid.Row="1" BackgroundColor="#D2D2D2" HeightRequest="1" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
<BoxView.Triggers>
<DataTrigger TargetType="BoxView" Binding="{Binding Source={x:Reference myEntry}, Path=IsFocused}" Value="true">
<Setter Property="BackgroundColor" Value="Black" />
<Setter Property="HeightRequest" Value="2"/>
</DataTrigger>
</BoxView.Triggers>
</BoxView>
</Grid>
</ControlTemplate>
Step 3: Create a super material design entry class
public class MyMaterialDesignEntry : ContentView, INotifyPropertyChanged
{
public static readonly BindableProperty TextProperty =
BindableProperty.Create("Text", typeof(string), typeof(ContentPage), "");
public static readonly BindableProperty IsPasswordProperty =
BindableProperty.Create("IsPassword", typeof(bool), typeof(ContentPage), false);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, (string)value); }
}
public bool IsPassword => (bool)GetValue(IsPasswordProperty);
public MyMaterialDesignEntry()
{
ControlTemplate = (ControlTemplate)Application.Current.Resources.FirstOrDefault(x => x.Key == "MyControlTemplate").Value;
}
}
Step 4: Use your super material design entry in xaml
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Label Text="Login"/>
<controls:MyMaterialDesignEntry Text="{Binding Login, Mode=TwoWay}"/>
</StackLayout>
Don't forget to add appropriate namespaces to your page xaml. It will tell you anyway.

How do I set the size of an image within a ListView?

How do I set the size of an image within a ListView?
The targeted device is Windows Phone 10 (i.e. Windows Universal Platform).
I've discovered the following documentation:
Note that when targeting Windows Phone 8.1, ImageCell will not scale
images by default. Also, note that Windows Phone 8.1 is the only
platform on which detail text is presented in the same color and font
as primary text by default. Windows Phone 8.0 renders ImageCell as
seen below:
I've tried:
<ListView Grid.Row="1" ItemsSource="{Binding Photos}" SelectedItem="{Binding SelectedPhoto, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding ImageSource}" Text="{Binding Description}" TextColor="Silver" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The above image shows a full-blown image without confining the size of the image to fit as a listview item.
I've also tried:
<ListView Grid.Row="1" ItemsSource="{Binding Photos}" SelectedItem="{Binding SelectedPhoto, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageSource}" Aspect="AspectFit" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The above code doesn't show any image. It just shows a white background.
Few things:-
ImageCell has no ability to specify the image width / height (v2.0.x).
Your second example is more on track, however, you need to wrap it in a ViewCell as you are dealing with a ListView like so:-
<ListView ItemsSource="{Binding Photos}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Image Source="{Binding MyImage}" Aspect="AspectFit" WidthRequest="{Binding MyWidth}" HeightRequest="{Binding MyHeight}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Also, note that the default for a ListView is set to have equal row heights.
Therefore if you have different image sizes, chances are this may not produce the output you want.
To get around this, specify HasUnevenRows='True'.
If you further do BindableProperties for what you want the ImageWidth and ImageHeight in your ViewModel, and specify them as in the example above using WidthRequest and HeightRequest for Image you will get something like this for the output when specifying different values:-
Just adding salt to a cooked meal, You can also do it dynamically:
<Slider x:Name="slider" Maximum="600" Minimum="30" />
<ListView RowHeight="55" x:Name="lv_prayers_categories_page"
ItemsSource="{Binding SimpleList}"
HasUnevenRows="true"
BackgroundColor="Transparent"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee" HeightRequest="50" >
<StackLayout Orientation="Horizontal">
<Image Aspect="AspectFill" Source="{Binding Image}" HeightRequest="{Binding Source={x:Reference slider}, Path=Value}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
<Label Text="{Binding Name}"
TextColor="#f35e20" />
<Label Text="{Binding ID}"
HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
View Modal:
private ObservableCollection<SimpleImage> _impleList;
public ObservableCollection<SimpleImage> SimpleList
{
get => _impleList;
set => SetProperty(ref _impleList, value);
}
SimpleList = new ObservableCollection<SimpleImage>()
{
new SimpleImage(){
ID = 0,
Name = "Female",
Image = "https://griffonagedotcom.files.wordpress.com/2016/07/profile-modern-2e.jpg"
},
new SimpleImage(){
ID = 1,
Name = "Male",
Image = "https://media.istockphoto.com/photos/profile-view-of-confident-sportsman-picture-id488758510?k=6&m=488758510&s=612x612&w=0&h=yIwLu2wdd2vo317STdyNlKYIVIEJEFfDKfkY8pBIfaA="
},
new SimpleImage(){
ID = 2,
Name = "Android",
Image = "https://www.cnn.co.jp/storage/2015/11/06/17626d508c2c2a8c8c322d353631a431/zuckerberg-getty.jpg"
},
};
Modal:
public class SimpleImage : BindableBase
{
private int _id;
public int ID
{
get { return _id; }
set { SetProperty(ref _id, value); }
}
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private ImageSource _image;
public ImageSource Image
{
get { return _image; }
set { SetProperty(ref _image, value); }
}
}

Resources