Xamarin Forms: accessing data in CollectionView - xaml

I'm unable to undestand how to access data in CollectionView DataTemplate generated child controls. My XAML code is below. I want to get RadioButton values of all items. Please give me some ideas.
<CollectionView x:Name="ItemsListView"
ItemsSource="{Binding Questions}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10" >
<Label Text="{Binding Category}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Label Text="{Binding Text}"
LineBreakMode="WordWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Grid HorizontalOptions="Fill" VerticalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RadioButton Content="Yes" Grid.Column="1" Style="{DynamicResource ListItemTextStyle}"/>
<RadioButton Content="No" Grid.Column="2" Style="{DynamicResource ListItemTextStyle}"/>
<RadioButton Content="N/A" Grid.Column="3" Style="{DynamicResource ListItemTextStyle}"/>
</Grid>
<Editor x:Name="comment" Text="" AutoSize="TextChanges" Style="{DynamicResource ListItemTextStyle}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>

As Jason and Steve suggested,the best practice is using MVVM.
Below is code snippet for your reference:
In your XAML:
<RadioButton Content="Yes" Grid.Column="1" IsChecked="{Binding YesChecked}" Style="{DynamicResource ListItemTextStyle}"/>
<RadioButton Content="No" Grid.Column="2" IsChecked="{Binding NoChecked}" Style="{DynamicResource ListItemTextStyle}"/>
<RadioButton Content="N/A" Grid.Column="3" IsChecked="{Binding N_AChecked}" Style="{DynamicResource ListItemTextStyle}"/>
Then in your view model,use like below:
public bool yesChecked;
public bool YesChecked
{
get { return yesChecked; }
set
{
yesChecked = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("YesChecked"));
}
}

Related

In WInUI 3 how can I pass ViewModel from a Page that has a UserControl

In a WinUI 3 application, using CommunityToolkit.Mvvm.
All ViewModels are created by a DI container.
The parent Page has a ViewModel and contains a child UserControl that also has a ViewModel.
Right now the UserControl DataContext is bound to the ViewModel like this:
<controls:AddEditControl x:Name="AddEditControl"
DataContext="{x:Bind ViewModel.UserDetailsViewModel}" />
What I tried to set ViewModel like this:
public sealed partial class AddEditControl : UserControl
{
public UserDetailsViewModel ViewModel
{
get;
}
public AddEditControl()
{
ViewModel = App.GetService<UserDetailsViewModel>();
this.InitializeComponent();
}
}
The issue is that setting a ViewModel in a code behind of the UserControl the same way its set in Page is not binding properly.
The goal is to be able to use the same x:Bind markup in the UserControl as in the Page.
<Page x:Class="SearchUserPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CSA2.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
xmlns:ctkControls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:customConverters="using:CSA2.Converters"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d"
Margin="-40">
<Page.Resources>
</Page.Resources>
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="0"
Margin="500 -78 60 0">
<StackPanel HorizontalAlignment="Right">
</StackPanel>
</Border>
<Grid x:Name="GridPanel"
Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="{x:Bind ViewModel.UserDetailsRowHeight, Mode=OneWay}"
MinHeight="40" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Margin="{StaticResource NavigationViewPageContentMargin}">
</Grid>
<Grid Grid.Row="1"
Margin="{StaticResource NavigationViewPageContentMargin}">
</Grid>
<Grid Grid.Row="2"
Background="#FAFAFA">
<TabView IsAddTabButtonVisible="False"
Background="#CCC">
<TabView.TabItems>
<TabViewItem x:Uid="UserDetailsTab"
IsClosable="False">
<controls:AddEditControl x:Name="AddEditControl"
DataContext="{x:Bind ViewModel.UserDetailsViewModel}" />
</TabViewItem>
<TabViewItem Header="History"
IsClosable="False">
<TextBlock Text="User History"
Style="{StaticResource SubheaderTextBlockStyle}"
Margin="10" />
</TabViewItem>
</TabView.TabItems>
</TabView>
</Grid>
</Grid>
</Grid>
</Page>
<UserControl x:Class="Controls.AddEditControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
xmlns:converters="using:CommunityToolkit.WinUI.UI.Converters"
mc:Ignorable="d">
<UserControl.Resources>
</UserControl.Resources>
<Grid Margin="{StaticResource NavigationViewPageContentMargin}"
Padding="0 0 0 40">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="7*" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0"
Command="{Binding EditUserCommand,Mode=TwoWay}"
IsChecked="{Binding IsEditButtonChecked, Mode=TwoWay}"
Margin="10"
HorizontalAlignment="Left"
Style="{ThemeResource DefaultToggleButtonStyle}"
Visibility="{Binding IsEditVisible, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal">
<Viewbox Style="{StaticResource ButtonIcon}">
<SymbolIcon Symbol="Edit" />
</Viewbox>
<TextBlock x:Uid="EditButton" />
</StackPanel>
</ToggleButton>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10 0"
Visibility="{Binding IsUserSelected, Converter={StaticResource BoolToVisibilityConverter}}">
<Button Command="{Binding SaveCommand}"
Style="{ThemeResource DefaultButtonStyle}"
Margin="10 0">
<StackPanel Orientation="Horizontal">
<Viewbox Style="{StaticResource ButtonIcon}">
<SymbolIcon Symbol="Save" />
</Viewbox>
<TextBlock x:Uid="SaveButton" />
</StackPanel>
</Button>
<Button Command="{Binding ResetCommand}">
<StackPanel Orientation="Horizontal">
<Viewbox Style="{StaticResource ButtonIcon}">
<SymbolIcon Symbol="Undo" />
</Viewbox>
<TextBlock x:Uid="ResetButton" />
</StackPanel>
</Button>
</StackPanel>
<StackPanel Grid.Column="1"
Margin="10"
VerticalAlignment="Center"
Visibility="{Binding IsUserSelected, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock x:Uid="UserFunctionsText"
Style="{StaticResource DetailSubTitleStyle}" />
</StackPanel>
</Grid>
<Grid Row="1"
Grid.Column="0"
Visibility="{Binding IsUserSelected, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="7*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0"
Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="8*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
</Grid.Resources>
<TextBlock x:Uid="UserIdText"
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}"
Visibility="{Binding IsCreateNewUser, Mode=TwoWay, Converter={StaticResource InverseBoolToVisibilityConverter}}" />
<TextBox x:Uid="UserIdText"
Grid.Row="0"
Grid.Column="1"
IsReadOnly="True"
Text="{Binding UserId, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox_ReadOnly}"
Visibility="{Binding IsCreateNewUser, Mode=TwoWay, Converter={StaticResource InverseBoolToVisibilityConverter}}" />
<TextBlock x:Uid="UserNameText"
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}" />
<TextBox x:Uid="UserNameNullText"
Grid.Row="1"
Grid.Column="1"
IsReadOnly="True"
Text="{Binding UserName, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox_ReadOnly}" />
<TextBlock x:Uid="UserEmailText"
Grid.Row="2"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}" />
<TextBox x:Uid="UserEmailNullText"
Grid.Row="2"
Grid.Column="1"
IsReadOnly="True"
Text="{Binding UserEmail, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox_ReadOnly}" />
<TextBlock x:Uid="UserDepartmentText"
Grid.Row="3"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}" />
<ComboBox Grid.Row="3"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode, Mode=TwoWay, Converter={StaticResource InverseBoolToVisibilityConverter}}"
IsEditable="False"
HorizontalAlignment="Stretch"
MaxDropDownHeight="180"
ItemsSource="{Binding UserDepartments}"
SelectedItem="{Binding UserDepartment, Mode=TwoWay}"
Style="{StaticResource EditForm_ComboBox}" />
<TextBox x:Uid="UserDepartmentNullText"
Grid.Row="3"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}"
IsReadOnly="{Binding ReadOnlyMode, Mode=TwoWay}"
Text="{Binding UserDepartment, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox}" />
<TextBlock x:Uid="UserStatusText"
Grid.Row="4"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}" />
<ComboBox Grid.Row="4"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode,Mode=TwoWay, Converter={StaticResource InverseBoolToVisibilityConverter}}"
IsEditable="False"
HorizontalAlignment="Stretch"
MaxDropDownHeight="180"
ItemsSource="{Binding UserStatus}"
SelectedItem="{Binding SelectedUserStatus, Mode=TwoWay}"
Style="{StaticResource EditForm_ComboBox}" />
<TextBox Grid.Row="4"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}"
IsReadOnly="{Binding ReadOnlyMode, Mode=TwoWay}"
Text="{Binding SelectedUserStatus, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox}" />
<TextBlock x:Uid="UserRoleText"
Grid.Row="5"
Grid.Column="0"
Style="{StaticResource EditForm_TextBlock}" />
<ComboBox x:Name="UserRoles"
Grid.Row="5"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode,Mode=TwoWay, Converter={StaticResource InverseBoolToVisibilityConverter}}"
HorizontalAlignment="Stretch"
MaxDropDownHeight="180"
IsEditable="False"
ItemsSource="{Binding UserRoles}"
SelectedItem="{Binding SelectedUserRole, Mode=TwoWay}"
Style="{StaticResource EditForm_ComboBox}">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="SelectionChanged">
<ic:InvokeCommandAction Command="{Binding SelectedItemCommand}"
CommandParameter="{x:Bind UserRoles.SelectedItem,Mode=OneWay}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</ComboBox>
<TextBox Grid.Row="5"
Grid.Column="1"
Visibility="{Binding ReadOnlyMode, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}"
IsReadOnly="{Binding ReadOnlyMode, Mode=TwoWay}"
HorizontalAlignment="Stretch"
Text="{Binding SelectedUserRole, Mode=TwoWay}"
Style="{StaticResource EditForm_TextBox}" />
</Grid>
<Grid Grid.Column="1"
Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
</Grid>
<Grid Row="2"
Visibility="{Binding IsEditButtonChecked, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="7*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="10 -50 10 0"
Visibility="{Binding IsUserSelected, Converter={StaticResource BoolToVisibilityConverter}}">
<Button Command="{Binding SaveCommand}"
Style="{ThemeResource DefaultButtonStyle}"
Margin="10 0">
<StackPanel Orientation="Horizontal">
<Viewbox Style="{StaticResource ButtonIcon}">
<SymbolIcon Symbol="Save" />
</Viewbox>
<TextBlock x:Uid="SaveButton" />
</StackPanel>
</Button>
<Button Command="{Binding ResetCommand}"
Style="{ThemeResource DefaultButtonStyle}">
<StackPanel Orientation="Horizontal">
<Viewbox Style="{StaticResource ButtonIcon}">
<SymbolIcon Symbol="Undo" />
</Viewbox>
<TextBlock x:Uid="ResetButton" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Grid>
</UserControl>
using CSA2.ViewModels;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace CSA2.Views;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SearchUserPage : Page
{
public SearchUserViewModel ViewModel
{
get;
}
public SearchUserPage()
{
ViewModel = App.GetService<SearchUserViewModel>();
InitializeComponent();
}
}

Xamarin collectionview is not scrolling smoothly

I am using collection view in Xamarin and I don't know what reason the scrolling is not smooth. I implemented compiled binding and increased the Garbage collector size in android. I would like any recommendation on how to optimize the collection view, or point out what the problem is.
<CollectionView x:DataType="viewmodels:PageViewModel" ItemsSource="{Binding ItemList}" >
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Item">
<StackLayout>
<BoxView HorizontalOptions="FillAndExpand" HeightRequest="5" Color="Silver"/>
<Grid RowSpacing="0" ColumnSpacing="0" Padding="15,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Row="0" Grid.ColumnSpan="2" Grid.Column="0" Orientation="Horizontal">
<ff:CachedImage Source="Image.jpg" HeightRequest="50" WidthRequest="50" HorizontalOptions="Start">
<ff:CachedImage.Transformations>
<ffTrans:CircleTransformation />
</ff:CachedImage.Transformations>
</ff:CachedImage>
<StackLayout HorizontalOptions="FillAndExpand" Padding="10,0,0,0">
<Label Text="{Binding Name}" FontSize="Small"/>
<Label Text="{Binding Date, StringFormat='{0:dd MMM yyyy}'}" FontSize="Small"/>
</StackLayout>
</StackLayout>
<ImageButton Grid.Row="0" BackgroundColor="Transparent" Grid.Column="2" IsVisible="True" Source="Icon.png" WidthRequest="30" HorizontalOptions="End">
<ImageButton.Triggers>
<DataTrigger TargetType="ImageButton" Binding="{Binding .}" Value="True" >
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
<DataTrigger TargetType="ImageButton" Binding="{Binding .}" Value="False" >
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</ImageButton.Triggers>
</ImageButton>
<ImageButton Grid.Row="0" BackgroundColor="Transparent" Grid.Column="2" IsVisible="False" Source="Icon.png" WidthRequest="30" HorizontalOptions="End">
<ImageButton.Triggers>
<DataTrigger TargetType="ImageButton" Binding="{Binding .}" Value="True" >
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</ImageButton.Triggers>
</ImageButton>
<ImageButton Grid.Row="0" BackgroundColor="Transparent" Grid.Column="2" IsVisible="False" Source="img.png" WidthRequest="30" HorizontalOptions="End">
<ImageButton.Triggers>
<DataTrigger TargetType="ImageButton" Binding="{Binding .}" Value="False" >
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</ImageButton.Triggers>
</ImageButton>
<ImageButton Grid.Row="0" BackgroundColor="Transparent" Grid.Column="2" Source="Icon.png" WidthRequest="20" HorizontalOptions="Center"/>
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Text="{Binding Text}" Margin="0,10"/>
<mediavideoplayer:VideoPlayer x:Name="mediaelement" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" IsEnabled="{Binding Attachments, Converter={StaticResource VideoVisibilityConverter}}" IsVisible="{Binding Attachments ,Converter={StaticResource VideoVisibilityConverter}}" DisplayControls="False" FillMode="ResizeAspectFill" HeightRequest="350" AutoPlay="True" Repeat="True">
<mediavideoplayer:VideoPlayer.Source>
<MultiBinding Converter="{StaticResource VideoUrlConverter}">
<Binding Path="Attachments.Path" />
<Binding Path="Attachments" />
</MultiBinding>
</mediavideoplayer:VideoPlayer.Source>
</mediavideoplayer:VideoPlayer>
<Image IsVisible="{Binding Attachments, Converter={StaticResource ImageVisibilityConverter}}" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Aspect="AspectFill" Style="{StaticResource StCommentPicture}">
<Image.Source>
<MultiBinding Converter="{StaticResource UrlConverter}">
<Binding Path="Attachments.path" />
<Binding Path="Attachments" />
</MultiBinding>
</Image.Source>
</Image>
<StackLayout Grid.Row="3" Grid.Column="0" >
<Label Text="👍" />
<Label Text="😍" />
<Label Text="😂" />
<Label x:Name="LikesCount" Grid.Row="5" Grid.Column="1" Text="{Binding likes}" />
</StackLayout>
<Label Grid.Row="3" Grid.Column="2" HorizontalOptions="End" Text="{Binding Comments, StringFormat='{0} Comments'}" Margin="0,6"/>
<BoxView Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" VerticalOptions="EndAndExpand" HeightRequest="1" Color="LightGray" Margin ="0,5"/>
<Frame Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" x:Name="likeArea" Opacity="0" Padding="0" HasShadow="true" OutlineColor="#EEEEEE" CornerRadius="70">
<Grid x:Name="GridlikeArea" Padding="5,0" BackgroundColor="Transparent" ColumnDefinitions="*,*,*,*,*" VerticalOptions="CenterAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<ImageButton x:Uid="Like" BackgroundColor="Transparent" Grid.Row="0" Grid.Column="0" Aspect="AspectFit" Source="Like.png" Clicked="LikeFrame_Clicked" ></ImageButton>
<ImageButton x:Name="Laugh" BackgroundColor="Transparent" Grid.Row="0" Grid.Column="1" Aspect="AspectFit" Source="Laugh.png" Clicked="LikeFrame_Clicked"></ImageButton>
<ImageButton x:Name="Love" BackgroundColor="Transparent" Grid.Row="0" Grid.Column="2" Aspect="AspectFit" Source="love.png" Clicked="LikeFrame_Clicked"></ImageButton>
<ImageButton x:Name="Sad" BackgroundColor="Transparent" Grid.Row="0" Grid.Column="3" Aspect="AspectFit" Source="sad.png" Clicked="LikeFrame_Clicked"></ImageButton>
<ImageButton x:Name="Hate" BackgroundColor="Transparent" Grid.Row="0" Grid.Column="4" Aspect="AspectFit" Source="angry.png" Clicked="LikeFrame_Clicked"></ImageButton>
</Grid>
</Frame>
<Button x:Name="LikeButton" HeightRequest="40" BackgroundColor="{Binding Reactions,Converter={StaticResource ReactionColorConverter}}"
CornerRadius="50" Grid.Row="5" Grid.Column="0" ImageSource="{Binding Reactions, Converter={StaticResource ReactionImageConverter}}" Text="Like" Clicked="LikeButton_Clicked" HorizontalOptions="StartAndExpand"/>
</Grid>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Footer>
<StackLayout HorizontalOptions="CenterAndExpand" Padding="0">
<Button BackgroundColor="Transparent" HorizontalOptions="CenterAndExpand" TextColor="#529dff" FontAttributes="Bold" Text="Load More..." Command="{Binding LoadMoreCommand}" Clicked="loadmorebutton_Clicked"/>
</StackLayout>
</CollectionView.Footer>
</CollectionView>
**Note: deleting the mediavideoplayer:VideoPlayer control wont make any difference **
The Issue is solved by the nuget Glidex. glidex.forms is small library we can use to improve Xamarin.Forms image performance on Android by taking a dependency on Glide. See my post on the topic here.

First-time user onboarding with Xamarin.Forms

I am implementing a first-time user onboarding in a Xamarin.Forms application like the one on the image below:
Please, how can I quickly do that?
Thank you in advance.
Do you want to achieve the result like following GIF?
You can use CarouselView and IndicatorView to achieve it.
Here is layout code.I dont adjust the layout like yours, you can adjust it by yourself, If you want to make Next and Skip Button over float the CarouselView, you can use AbsoluteLayout
<StackLayout Margin="10">
<CarouselView x:Name="myCarouselView" ItemsSource="{Binding Monkeys}"
IndicatorView="indicatorView">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="50"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Image Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="150"
WidthRequest="150"
HorizontalOptions="Center" />
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="Skip" Grid.Column="0" BackgroundColor="Transparent" Clicked="Button_Clicked"></Button>
<Button Text="Next" Grid.Column="1" BackgroundColor="Transparent" Clicked="Button_Clicked_1"></Button>
</Grid>
<IndicatorView x:Name="indicatorView"
MaximumVisible="6"
Margin="0,0,0,40"
IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"
HorizontalOptions="Center" />
</StackLayout>
Here is layout bakground code.
public partial class BasicIndicatorViewPage : ContentPage
{
int monkeyCount;
public BasicIndicatorViewPage()
{
InitializeComponent();
MonkeysViewModel monkeysViewModel= new MonkeysViewModel();
monkeyCount = monkeysViewModel.Monkeys.Count;
BindingContext = monkeysViewModel;
}
private void Button_Clicked(object sender, System.EventArgs e)
{
Navigation.PushAsync(new Page1());
Navigation.RemovePage(this);
}
private void Button_Clicked_1(object sender, System.EventArgs e)
{
if (myCarouselView.Position < monkeyCount-1)
{
myCarouselView.Position += 1;
}
else
{
Navigation.PushAsync(new Page1());
Navigation.RemovePage(this);
}
}
}
Here is my demo, you can download it.
https://github.com/851265601/XFormsCarouselView-IndicatorViewLoginPage
If you want to put the indicatorView and Button in the same line like this screenshot.
You can use this layout(indicatorView to the Grid).
<StackLayout Margin="10">
<CarouselView x:Name="myCarouselView" ItemsSource="{Binding Monkeys}"
IndicatorView="indicatorView">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="50"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Image Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="150"
WidthRequest="150"
HorizontalOptions="Center" />
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="Skip" Grid.Column="0" BackgroundColor="Transparent" Clicked="Button_Clicked"></Button>
<IndicatorView x:Name="indicatorView"
MaximumVisible="6"
IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"
HorizontalOptions="Center" Grid.Column="1" />
<Button Text="Next" Grid.Column="2" BackgroundColor="Transparent" Clicked="Button_Clicked_1"></Button>
</Grid>
</StackLayout>
You could use the offical Xamarin.Forms CarouselView but that's still in preview. You could also potentially look at the Sharpnado's solution with HorizontalListView. Your third option would be to use Alex Rainman's CarouselView.

Xamarin aligning items in List View

I am using the following xaml in xamrin forms to create an order details page with the list of orders in a sub list-view however I am having a biit of difficulty in aligning the list view items.
<ContentPage.Content>
<ScrollView>
<StackLayout Spacing="2">
<Label Text="Order Number:"></Label>
<Label Text="{Binding Item.SopOrderNumber}"
LineBreakMode="NoWrap"
FontSize="20" />
<Label Text="Phone Number:" FontSize="20" ></Label>
<Label Text="{Binding Item.TelephoneNumber}"/>
<Button Command="{Binding SubmitCommand}" Text="Click To Call" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" />
<Label Text="{Binding Item.CustomerName}"
LineBreakMode="NoWrap"
FontSize="20" />
<Label Text="Order Status"
HorizontalOptions="StartAndExpand" />
<Picker x:Name="picker" Title="Order Status">
<Picker.ItemsSource >
<x:Array Type="{x:Type x:String}">
<x:String>Delivered</x:String>
<x:String>Damaged</x:String>
<x:String>Missing</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Label Text="Order Details" FontSize="Large"></Label>
<ListView x:Name="DeliveryItemsList" HeightRequest="80" HasUnevenRows="True" >
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Horizontal" Padding="10" Spacing="15">
<Label Text="{Binding ItemNumber}" FontSize="20" ></Label>
<Label Text="{Binding StockCode}" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding StockDescription}" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding Price}" TextColor="Gray" FontSize="20" ></Label>
<Label Text="{Binding Qty}" TextColor="Gray" FontSize="20" ></Label>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Label Text="Notes"
HorizontalOptions="StartAndExpand"
/>
<Editor x:Name="txtNotes"
VerticalOptions="FillAndExpand" HeightRequest="20"></Editor>
<Sig:SignaturePadView x:Name="signaturePad" />
<Image x:Name="PhotoSource" ></Image>
<Button Command="{Binding SubmitCommand}" Text="Take Picture of Delivery" x:Name="btnTakePhto" Clicked="BtnTakePhto_Clicked" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" />
<Button Text="Update Order" BackgroundColor="AliceBlue" Clicked="Update_Order_Clicked"></Button>
<Button Text="Update Order and Goto Next Job" BackgroundColor="AliceBlue" Clicked="Update_Order_Clicked"></Button>
</StackLayout>
</ScrollView>
</ContentPage.Content>
As you can see from the image the items in the Listview are not in line with each other how can i make them so aligned.
Edit 2
Hi Again I AM afraid I tried the below answer but it didn't work in end it looked sound.
<ListView x:Name="DeliveryItemsList" HeightRequest="80" HasUnevenRows="True" >
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<Label Text="{Binding ItemNumber}" FontSize="20" ></Label>
<Label Text="{Binding StockCode}" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding StockDescription}" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding Price}" TextColor="Gray" FontSize="20" ></Label>
<Label Text="{Binding Qty}" TextColor="Gray" FontSize="20" ></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
If you want things to align, StackLayout is probably not the way to do it. StackLayout allocates space to each child element based on how much it needs, so if each row in your list has differing width requirements for different elements, like price, you'll get the kind of layout you see.
A better approach would be Grid, which gives you explicit control over how wide each column is:
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<Label Text="{Binding ItemNumber}" Grid.Column="0" FontSize="20" ></Label>
<Label Text="{Binding StockCode}" Grid.Column="1" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding StockDescription}" Grid.Column="2" FontSize="20" TextColor="Gray"></Label>
<Label Text="{Binding Price}" Grid.Column="3" TextColor="Gray" FontSize="20" ></Label>
<Label Text="{Binding Qty}" Grid.Column="4" TextColor="Gray" FontSize="20" ></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
In this example, each column is defined to have an equal width (dividing the available width evenly), but you can adjust as you see fit.
You could change one of the ColumnDefinitions to Width="1.5*" which would allocate 1.5 times the space to that column as it does to the other columns. Or could you define a column with Width="100" which would give it a fixed size regardless of the width of the screen.
There is also Width="Auto" which lets you set the width of the column based on the amount of space needed by the contents of that column, but since each row in your ListView is a different Grid, you'd end up with the same problem as you are having now with StackLayout.

How to use Grid and create this?

i would like to create a view like this :
. Where Contact1, Contact2 are models and ListViewis a list of these models.
Now i have code like this but i dont get the desired output.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="KiaiDay.Pages.ConviteEmailPage"
NavigationPage.TitleView="Convive por email"
NavigationPage.HasBackButton="True"
NavigationPage.BackButtonTitle="Voltar"
BackgroundColor="AliceBlue">
<ContentPage.Content>
<AbsoluteLayout>
<ActivityIndicator x:Name="indicador" AbsoluteLayout.LayoutBounds="0.5,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional" Color="Blue"/>
<StackLayout>
<ListView x:Name="ListaContactos">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Image Source="{Binding Imagem}"/>
<Label Text="{Binding Nome}"/>
<Label Text="{Binding Email}"/>
<Label Text="{Binding Numero}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
As Jason said, you can use CollectionView to do it.However,you should note that:
The CollectionView is currently an early preview, and lacks much of its planned functionality. In addition, the API will change as the implementation is completed.
And CollectionView is available in Xamarin.Forms 4.0-pre1.
If no problem with version, using code as follow:(Update: Adding Frame to code)
<StackLayout Margin="20,35,20,20">
<CollectionView ItemsSource="{Binding Monkeys}" >
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<Frame BackgroundColor="LightGray"
OutlineColor="Black"
CornerRadius="10">
<Grid Padding="5" WidthRequest="120" HeightRequest="120">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Image Grid.Row="1"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Row="2"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
<Label Grid.Row="3"
Text="{Binding Details}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
Refer to official sample , binding source:
BindingContext = new MonkeysViewModel();
Here is the capture image of app.