CollectionView items animation - xamarin

I'm creating application with chat function. I made simple 'typing indicator' that shows new item in collectionView (Label) with text 'User is typing...'. So now i would like to animate this Label or add some animation like 3 dots that indicates user is typing. Is it somehow possible to make something like this? Any help appreciated, Thank you.
#EDIT
Code below describes my Chat layout:
<ContentPage.Content>
<StackLayout x:Name="content_stackLayout">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<CollectionView
x:Name="chat_collectionView"
Grid.Row="0"
VerticalOptions="Start"
HorizontalOptions="Center"
ItemSizingStrategy="MeasureAllItems"
SelectionMode="None"
ItemsSource="{Binding Messages}"
ItemsUpdatingScrollMode="KeepLastItemInView"
>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="{Binding messageAlignment}" Margin="30,5,30,5">
<Image
Source="{Binding image}"
Margin="{Binding imageMargin}"
HeightRequest="40"
WidthRequest="40"
Aspect="AspectFit" />
<Frame
BorderColor="Black"
CornerRadius="{Binding cornerRadius}"
BackgroundColor="{Binding kolorWiadomosci}"
Margin="{Binding messageMargin}">
<Label
Text="{Binding message}"
FontAttributes="{Binding textAttribute}"
x:Name="label"
FontSize="Title"
VerticalOptions="CenterAndExpand" />
</Frame>
</StackLayout>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout
Grid.Row="1"
Orientation="Horizontal"
x:Name="sendMessage_stackLayout"
HeightRequest="80"
Padding="8"
>
<Entry
Margin="10,10,0,5"
Placeholder="your message..."
ClassId="message_entry"
x:Name="message_entry_label"
HorizontalOptions="FillAndExpand"
ClearButtonVisibility="WhileEditing"
Keyboard="Chat"
ReturnType="Send"
TextColor="Black"
BackgroundColor="#2596be"
/>
<Button
WidthRequest="200"
HeightRequest="30"
Text="Send"
FontSize="Title"
x:Name="button_send_label"
HorizontalOptions="End"
Clicked="Button_Clicked"
BorderWidth="5"
BorderColor="Black"
CornerRadius="5"
/>
</StackLayout>
</Grid>
</StackLayout>
</ContentPage.Content>
I've got binding with viewModel which receives messages from another App with SignalR, creates a new messages and adds them to List called "Messages" like below:
public class Message
{
public string message{ get; set; }
//public Thickness messageMargin{ get; set; }
public string image{ get; set; }
//public Thickness imageMargin{ get; set; }
public FontAttributes textAttribute{ get; set; }
public string author{ get; set; }
public LayoutOptions messageAlignment{ get; set; }
public Color textColor{ get; set; }
public double cornerRadius { get; set; }
}
So now when another person in second App is typing, it fires SignalR boolean method that my 'Chat App' receives. If UserTyping = true - App adds new message saying 'User is typing'. I would like to animate it somehow or if not possible, develop another solution for this behaviour.

Related

Change item control property of checked listview item Xamarin.Forms

Hy,
I am trying to show a comment input if the item checkbox is checked and hide it else, i have this XAML
<ListView ItemsSource="{Binding TaskItems}" x:Name="TasksItems" HasUnevenRows="True" VerticalScrollBarVisibility="Default" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout IsVisible="True" Orientation="Vertical">
<Grid BackgroundColor="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackLayout Grid.Column="0" Grid.Row="0">
<input:CheckBox Type="Box" IsChecked="{Binding TaskChecked , Mode=TwoWay}"/>
</StackLayout>
<StackLayout Grid.Column="0" Grid.Row="1" IsVisible="{Binding CommentRequired}">
<Entry BackgroundColor="White" PlaceholderColor="Black" HeightRequest="40" TextColor="Black"/>
</StackLayout>
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
and i have this c# code to read the items from database
public class TaskData
{
public bool TaskChecked { get; set; }
public bool CommentRequired { get; set; }
}
public partial class HomePage : ContentPage
{
public HomePage()
{
ObservableCollection<TaskData> TaskItems { get; set; }
ObservableCollection<TaskData> TasksList;
TaskItems = new ObservableCollection<TaskData>();
//Loop the tasks from database result
While...
TaskItems.Add(new TaskData
{
TaskChecked = false,
CommentRequired = false,
});
//End Loop
TasksListView.ItemsSource = TaskItems;
}
}
Now i need to add a "CheckChanged" event to show the comment Entry (IsVisible="True") when the user check the checkbox of the targed listview item
Thanks
First add the event.
<input:CheckBox Type="Box" IsChecked="{Binding TaskChecked , Mode=TwoWay}" CheckedChanged="OnCheckBoxCheckedChanged"/>
Add Name for the second stack
<StackLayout x:Name="StackLayoutEntry" Grid.Column="0" Grid.Row="1" IsVisible="{Binding CommentRequired}">
<Entry BackgroundColor="White" PlaceholderColor="Black" HeightRequest="40" TextColor="Black"/>
</StackLayout>
Then in code Behind use this function to find the entry for the clicked checkbox
void OnCheckBoxCheckedChanged(object sender, CheckedChangedEventArgs e)
{
var Sender = (CheckBox)sender;
var stacklayoutentry = Sender.Parent.FindByName<StackLayout>("StackLayoutEntry");
stacklayoutentry.IsVisible = True;
}
This might also help you also Check
Another approach but you an identifier to your selected item.
Check

Xamarin Forms CollectionView Grouping Not Working With Intellisense

The Issue
I am getting extremely confused with how grouping works in the CollectionView.
I am able to get an output as expected using the recommended example from the Xamarin Documentation with the code below:
CollectionView XAML
<CollectionView IsGrouped="True" ItemsSource="{Binding CategoriesList}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" ItemSpacing="10" />
</CollectionView.ItemsLayout>
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label Text="{Binding Name}" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Delete" IconImageSource="CategoryPhoto" />
</SwipeItems>
</SwipeView.LeftItems>
<SwipeView.RightItems>
<SwipeItems>
<SwipeItem Text="Edit" IconImageSource="CategoryPhoto" />
</SwipeItems>
</SwipeView.RightItems>
<SwipeView.Content>
<StackLayout BackgroundColor="Red">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.EditProduct, Source={x:Reference Name=MainView}}" CommandParameter="{Binding ID}" />
</StackLayout.GestureRecognizers>
<StackLayout Orientation="Horizontal" Padding="15">
<Image Source="CategoryPhoto" />
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" TextColor="Black" />
<Label Text="doy" TextColor="Black" />
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand">
<Label Text="⊖" TextColor="Black" VerticalTextAlignment="Center" RelativeLayout.HeightConstraint="{ConstraintExpression Property=Height, Factor=1, Type=RelativeToParent}">
<Label.GestureRecognizers>
<!--<TapGestureRecognizer Command="{Binding Path=BindingContext.RemoveItem, Source={x:Reference Name=MainView}}" CommandParameter="{Binding ID}" />-->
</Label.GestureRecognizers>
</Label>
<Label x:Name="QuantityLabel" Text="{Binding Quantity}" TextColor="Black" VerticalTextAlignment="Center" />
<Label Text="⊕" TextColor="Black" VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<!--<TapGestureRecognizer Command="{Binding Path=BindingContext.PurchaseItem, Source={x:Reference Name=MainView}}" CommandParameter="{Binding ID}" />-->
</Label.GestureRecognizers>
</Label>
</StackLayout>
</StackLayout>
<Rectangle Fill="LightGray" HeightRequest="2" />
</StackLayout>
</SwipeView.Content>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Product Class
using System;
using System.ComponentModel;
using SQLite;
using SQLiteNetExtensions.Attributes;
namespace TakeItAwayPOS.Structures
{
public class Product
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Stock { get; set; }
[ForeignKey(typeof(Category))]
public int Category { get; set; }
//for adding to orders
[Ignore]
private int quantity { get; set; }
public int Quantity
{
get => quantity;
set { quantity = value; QuantityChanged(); }
}
public delegate void PropertyChangedEvent(object sender, PropertyChangedEventArgs args);
public event PropertyChangedEvent PropertyChanged;
private void QuantityChanged()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
}
}
CategoryGroup Class
using System;
using System.Collections.Generic;
namespace TakeItAwayPOS.Structures
{
public class CategoryGroup : List<Product>
{
public string Name { get; private set; }
public CategoryGroup(string name, List<Product> products) : base(products)
{
Name = name;
}
}
}
EditProduct Command
public ICommand EditProduct
{
get
{
return new Command<string>((param) =>
{
Console.WriteLine("Triggered!");
LoadProduct(Convert.ToInt32(param));
});
}
}
My issue is with the GestureRecogniser for the StackLayout inside of the DataTemplate:
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.EditProduct, Source={x:Reference Name=MainView}}" CommandParameter="{Binding ID}" />
</StackLayout.GestureRecognizers>
the CommandParameter binding wont work and the Command is only fired if I replace "{Binding ID}" with "0":
When I hover over all of the binding items in the CollectionView, intellisense references them to the CategoryGroup type instead of the Product type that would be expected, the odd thing is that the other binding values except the Command all work even though intellisense references them to the wrong type.
My two questions are:
How would I go about trying to fix that command
Can I fix the intellisense so that it recognises when grouping is true (or is this a known issue?)
Thanks in advance!
Solved
Thanks #Jason!
For some reason earlier in my code, the CommandParameter didn't want to work as an int and so I had used this long winded method that converted to a string and then back to an int within the Command's lambda method. Turns out I didn't need this and the fix was just to change the parameter type of the Command to int as so:
public ICommand EditProduct
{
get
{
return new Command<int>((param) =>
{
Console.WriteLine("Triggered!");
LoadProduct(param);
});
}
}
ID is an int, so you need to use Command<int>, not Command<string>

How to share View Model between pages?

I can add data to the viewmodel, but when I try to access the same viewmodel from another page, the data is lost. How can I use the same viewmodel across multiple pages?
ViewModel Code
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;
namespace App1
{
class DebtViewModel
{
ObservableCollection<Debt> _Debt = new ObservableCollection<Debt>();
public System.Windows.Input.ICommand AddAccountCommand => new Command(AddAccount);
public System.Windows.Input.ICommand RemoveAccountCommand => new Command(RemoveAccount);
public System.Windows.Input.ICommand UpdateAccountCommand => new Command(UpdateAccount);
public ObservableCollection<Debt> Debt { get; set; }
public string Account { get; set; }
public string SelectedAccount { get; set; }
public double AnnualPercentageRate { get; set; }
public decimal Amount { get; set; }
public decimal MonthlyPayment { get; set; }
public bool IntroductoryRate { get; set; }
public double IntroductoryPercentageRate { get; set; }
public int IntroductoryRange { get; set; }
public DebtViewModel()
{
ObservableCollection<Debt> Debts = _Debt;
}
public void AddAccount()
{
var debt = new Debt(Account, Amount, AnnualPercentageRate, MonthlyPayment, IntroductoryRate,
IntroductoryPercentageRate, IntroductoryRange);
if (Account != null)
{
_Debt.Add(debt);
}
}
public void RemoveAccount()
{
//Debt.Remove(SelectedAccount);
}
public void UpdateAccount()
{
//int newIndex = Debt.IndexOf(SelectedAccount);
//Debt.Remove(SelectedAccount);
//Debt.Add(Account);
//int oldIndex = Debt.IndexOf(Account);
//Debt.Move(oldIndex, newIndex);
}
}
}
List Page
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:App1"
mc:Ignorable="d"
x:Class="App1.ListViewPage">
<!-- Required to map viewmodel -->
<ContentPage.BindingContext>
<local:DebtViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add"></ToolbarItem>
</ContentPage.ToolbarItems>
<!-- Bind variable in view model to listview itemsource -->
<ContentPage.Content>
<StackLayout>
<!--<Entry Placeholder="Account"
Text="{Binding Account}"/>
<Button Text="Add" Command="{Binding AddAccountCommand}"></Button>
<Button Text="Remove" Command="{Binding RemoveAccountCommand}"></Button>
<Button Text="Update" Command="{Binding UpdateAccountCommand}"></Button>-->
<!--textcell, custom cells, or image cell-->
<ListView ItemsSource="{Binding Debt}" SelectedItem="{Binding SelectedAccount}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding AccountName}"
FontSize="Medium"
VerticalTextAlignment="Start"
Grid.Column="0"></Label>
<Label Text="Balance"
VerticalTextAlignment="Start"
Grid.Column="1"></Label>
<Label Text="{Binding InitialAmount}"
VerticalTextAlignment="End"
Grid.Column="1"></Label>
<Label Text="APR"
VerticalTextAlignment="Start"
Grid.Column="2"></Label>
<Label Text="{Binding AnnualPercentageRate}"
VerticalTextAlignment="End"
Grid.Column="2"></Label>
<Label Text="Monthly Payment"
VerticalTextAlignment="Start"
Grid.Column="3"></Label>
<Label Text="{Binding MonthlyPayment}"
VerticalTextAlignment="End"
Grid.Column="3"></Label>
<Image Source="edit.png" Grid.Column="4"></Image>
<Image Source="trash.jpg" Grid.Column="5"></Image>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Add Page
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:App1"
mc:Ignorable="d"
x:Class="App1.ListViewPage">
<!-- Required to map viewmodel -->
<ContentPage.BindingContext>
<local:DebtViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add"></ToolbarItem>
</ContentPage.ToolbarItems>
<!-- Bind variable in view model to listview itemsource -->
<ContentPage.Content>
<StackLayout>
<!--<Entry Placeholder="Account"
Text="{Binding Account}"/>
<Button Text="Add" Command="{Binding AddAccountCommand}"></Button>
<Button Text="Remove" Command="{Binding RemoveAccountCommand}"></Button>
<Button Text="Update" Command="{Binding UpdateAccountCommand}"></Button>-->
<!--textcell, custom cells, or image cell-->
<ListView ItemsSource="{Binding Debt}" SelectedItem="{Binding SelectedAccount}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding AccountName}"
FontSize="Medium"
VerticalTextAlignment="Start"
Grid.Column="0"></Label>
<Label Text="Balance"
VerticalTextAlignment="Start"
Grid.Column="1"></Label>
<Label Text="{Binding InitialAmount}"
VerticalTextAlignment="End"
Grid.Column="1"></Label>
<Label Text="APR"
VerticalTextAlignment="Start"
Grid.Column="2"></Label>
<Label Text="{Binding AnnualPercentageRate}"
VerticalTextAlignment="End"
Grid.Column="2"></Label>
<Label Text="Monthly Payment"
VerticalTextAlignment="Start"
Grid.Column="3"></Label>
<Label Text="{Binding MonthlyPayment}"
VerticalTextAlignment="End"
Grid.Column="3"></Label>
<Image Source="edit.png" Grid.Column="4"></Image>
<Image Source="trash.jpg" Grid.Column="5"></Image>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
As Jason said: If you specify the VM in XAML it will create a new instance for each page. They are totally different.
How can I use the same viewmodel across multiple pages?
There are many ways to do it.
For example, you can define/create a static ViewModel in App.cs:
public partial class App : Application
{
public static DebtViewModel sharedViewModel { get; set; }
public App()
{
InitializeComponent();
MainPage = new MainPage();
createViewModel();
}
public void createViewModel() {
sharedViewModel = new DebtViewModel();
}
public class DebtViewModel {
}
}
Then in other page, you can set this ViewModel as page's bindingContext:
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
this.BindingContext = App.sharedViewModel;
}
}
Pass the instance to the new page on the constructor in also a solution.

Any idea how to add CarouselView indicators inside the CarouselView it self?

I am using a CarouselView to display a few views
each one of them is basically 2 StackLayouts
like so
what I have done so far is create a CarouselView with a template for both of these Stacklayouts
<CarouselView
x:Name="MyCarouselView"
IsVisible="{Binding ShouldShow}"
ItemsSource="{Binding MyItemSource}"
Scrolled="CarouselView_Scrolled">
<CarouselView.ItemTemplate>
<DataTemplate>
<ContentView>
<FlexLayout Direction="Column" JustifyContent="SpaceBetween">
<StackLayout FlexLayout.Basis="25%">
<elements:TopView Data="{Binding}"/>
</StackLayout>
<StackLayout FlexLayout.Basis="75%">
<elements:BottomView Data="{Binding}"/>
</StackLayout>
</FlexLayout>
</ContentView>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Note: the views bind to different values but for simplicity sake, I wrote a simpler DataTemplate here.
it works fine and there is no problem in binding or anything
what I am trying to do is add indicators to show the user that there are more items and which one he is seeing now. (small circles or something like that).
the thing is I want to display them between the two views like so
Any idea of how to do it?
Any other way to achieve the wanted result is welcome as well
Please and thank you.
The easy way to implement that is using Grid to do that :
<Grid>
<!-- Place new controls here -->
<CarouselView x:Name="CustomCarouselView"
IndicatorView="indicatorView"
VerticalOptions="FillAndExpand"
>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<ContentView BackgroundColor="LightBlue" >
<Label Text="{Binding TopViewTitle}" FontSize="Header" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" HeightRequest="250"/>
</ContentView>
<ContentView BackgroundColor="LightGray" Margin="0,80,0,0">
<Label Text="{Binding BottomViewTitle}" FontSize="Header" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" HeightRequest="250" />
</ContentView>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="indicatorView"
IndicatorsShape="Square"
IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"
VerticalOptions="Center"
Margin="0,-150,0,0" />
</Grid>
Above is my sample xaml code ,only need to custom the Margin property of IndicatorView and bottom ContentView after binding ItemSource for CarouselView :
List<CarouselModel> carouselModels = new List<CarouselModel>();
carouselModels.Add(new CarouselModel { TopViewTitle = "first top", BottomViewTitle = "first bottom" });
carouselModels.Add(new CarouselModel { TopViewTitle = "second top", BottomViewTitle = "second bottom" });
carouselModels.Add(new CarouselModel { TopViewTitle = "third top", BottomViewTitle = "third bottom" });
CustomCarouselView.ItemsSource = carouselModels;
The effect shows as expected :
The another way you can use RelativeLayout to implement that :
<RelativeLayout>
<!-- Place new controls here -->
<CarouselView x:Name="CustomCarouselView"
IndicatorView="indicatorView"
>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<ContentView BackgroundColor="LightBlue">
<Label Text="{Binding TopViewTitle}"
FontSize="Header"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
HeightRequest="250" />
</ContentView>
<ContentView BackgroundColor="LightGray"
Margin="0,80,0,0">
<Label Text="{Binding BottomViewTitle}"
FontSize="Header"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
HeightRequest="250" />
</ContentView>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="indicatorView"
IndicatorsShape="Square"
IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.5,Constant=-25}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.5,Constant=-75}"
/>
</RelativeLayout>
Here you can modify RelativeLayout.XConstraint and RelativeLayout.YConstraint of IndicatorView to set the space between two ContentView . The Margin property
of Bottom ContentView also need to set , it's effect is to show the space between two ConentView .
You can achieve this in two methods :-
Grid, where you can place both the controls in the same Grid.Row.
Assign VerticalOptions="FillAndExpand" to the CarouselView and VerticalOptions="Center" to the IndicatorView.
By Using AbsoluteLayout.
Let me know if you have more queries.
We can achieve this scenario by placing a carousel view inside the parent carousel view and providing the Indicator view for the carousel placed inside.
Also we need to bind the "Position" property of inside carousel view properly, so that indicator view points to the proper selected index. Please find the code below for reference,
Inside Xaml:
<StackLayout Padding="30">
<CarouselView x:Name="MyCarouselView"
ItemsSource="{Binding MyItemSource}"
FlowDirection="MatchParent">
<CarouselView.ItemTemplate>
<DataTemplate>
<ContentView>
<FlexLayout Direction="Column"
JustifyContent="SpaceBetween"
BackgroundColor="Pink">
<StackLayout FlexLayout.Basis="5%">
<BoxView HeightRequest="100"
WidthRequest="100"
BackgroundColor="{Binding Boxview1Color}" />
</StackLayout>
<CarouselView FlexLayout.Basis="0%"
IndicatorView="indicatorView"
IsSwipeEnabled="False"
ItemsSource="{Binding Items}"
Position="{Binding Position}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding ItemText}"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="indicatorView"
FlexLayout.Basis="10%"
HeightRequest="10"
IndicatorsShape="Circle"
IndicatorColor="White"
SelectedIndicatorColor="DarkBlue">
</IndicatorView>
<StackLayout FlexLayout.Basis="60%">
<BoxView HeightRequest="100"
WidthRequest="100"
BackgroundColor="{Binding Boxview2Color}"/>
</StackLayout>
</FlexLayout>
</ContentView>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
Inside ViewModel:
public class MainPageViewModel
{
private ObservableCollection<MyItemSourceViewModel> _myItemSource;
public ObservableCollection<MyItemSourceViewModel> MyItemSource { get; set; }
public MainPageViewModel()
{
MyItemSource = new ObservableCollection<MyItemSourceViewModel>();
MyItemSource.Add(new MyItemSourceViewModel { Boxview1Color = Color.Red, Boxview2Color = Color.Blue, Position = 0 });
MyItemSource.Add(new MyItemSourceViewModel { Boxview1Color = Color.Green, Boxview2Color = Color.Purple, Position = 1});
MyItemSource.Add(new MyItemSourceViewModel { Boxview1Color = Color.PeachPuff, Boxview2Color = Color.Brown, Position = 2 });
var count = MyItemSource.Count;
foreach(var item in MyItemSource)
{
var itemCount = count;
var i = 0;
item.Items = new List<ItemsModel>();
while(itemCount > 0)
{
var itemModel = new ItemsModel { ItemText = i.ToString()};
item.Items.Add(itemModel);
i++;
itemCount--;
}
}
}
}
public class MyItemSourceViewModel
{
public Color Boxview1Color { get; set; }
public Color Boxview2Color { get; set; }
public int Position { get; set; }
public List<ItemsModel> Items { get; set; }
}
public class ItemsModel
{
public string ItemText { get; set; }
}
Please refer below screenshots as well:
Sample screenshot 1
Sample screenshot 2

Serialize Class Xamarin.Forms

I’m trying to serialize class but I can’t do it.
I have a class below:
public class DadosTitulo
{
public string nome { get; set; }
public string numeroCpfCnpj { get; set; }
public string logradouro { get; set; }
public string numero { get; set; }
public string complemento { get; set; }
public string bairro { get; set; }
public string cep { get; set; }
public string municipio { get; set; }
public string uf { get; set; }
public double valor { get; set; }
public string numeroDocumento { get; set; }
public string dataVencimento { get; set; }
public string celularDestino { get; set; }
public bool registroProducao { get; set; }
}
And in my MainPage.xaml.cs I have:
private async void btnAdicionar_Clicked(object sender, EventArgs e)
{
var retorno = "";
var titulo = new DadosTitulo
{
nome = txtNome.Text,
numeroCpfCnpj = txtNumeroCpfCnpj.Text,
logradouro = txtLogradouro.Text,
numero = txtNumero.Text,
complemento = txtComplemento.Text,
bairro = txtBairro.Text,
cep = txtCep.Text,
municipio = txtMunicipio.Text,
uf = txtUF.Text,
valor = Convert.ToDouble(txtValor.Text),
numeroDocumento = txtNumeroDocumento.Text,
dataVencimento = DataVencimento.Date.ToString("dd/MM/yyyy"),
celularDestino = txtDddCelularDestino.Text + txtNumCelularDestino.Text,
registroProducao = RegistraProducao
};
var registroService = new RegistroBoletoService();
retorno = registroService.RegistrarBoleto(titulo);
await DisplayAlert("Json", retorno, "OK");
}
Property Values from MainPage.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:local="clr-namespace:AppRegistraBoletoXF"
x:Class="AppRegistraBoletoXF.MainPage">
<StackLayout Orientation="Vertical">
<StackLayout>
<Label Text="Registra Boleto" TextColor="Indigo" FontSize="Medium" />
</StackLayout>
<StackLayout>
<Label Text="Informe os dados do Título:" TextColor="Black" FontSize="Small" />
</StackLayout>
<StackLayout>
<Entry x:Name="txtNome" Placeholder="Nome" HorizontalOptions="Start"
VerticalOptions="StartAndExpand" HeightRequest="35" WidthRequest="300" FontSize="Small"/>
<Entry x:Name="txtNumeroCpfCnpj" Placeholder="CPF/CNPJ" HorizontalOptions="Start"
VerticalOptions="StartAndExpand" HeightRequest="35" WidthRequest="300" FontSize="Small" />
<StackLayout Orientation="Horizontal">
<Entry x:Name="txtLogradouro" Placeholder="Logradouro" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="160" FontSize="Small" />
<Entry x:Name="txtNumero" Placeholder="Número" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="50" FontSize="Small" />
<Entry x:Name="txtComplemento" Placeholder="Complemento" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="90" FontSize="Small" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Entry x:Name="txtBairro" Placeholder="Bairro" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="180" FontSize="Small" />
<Entry x:Name="txtCep" Placeholder="CEP" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="120" FontSize="Small" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Entry x:Name="txtMunicipio" Placeholder="Município" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="250" FontSize="Small" />
<Entry x:Name="txtUF" Placeholder="UF" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="50" FontSize="Small" />
</StackLayout>
<StackLayout Orientation="Horizontal">
<Entry x:Name="txtDddCelularDestino" Placeholder="DDD" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="50" FontSize="Small" />
<Entry x:Name="txtNumCelularDestino" Placeholder="Celular Destino" HorizontalOptions="StartAndExpand" VerticalOptions="Start"
HeightRequest="35" WidthRequest="250" FontSize="Small" />
</StackLayout>
<Entry x:Name="txtNumeroDocumento" Placeholder="Número do Título" HorizontalOptions="Start"
VerticalOptions="StartAndExpand" HeightRequest="35" WidthRequest="300" FontSize="Small"/>
<Entry x:Name="txtValor" Placeholder="Valor do Título" HorizontalOptions="Start"
VerticalOptions="StartAndExpand" HeightRequest="35" WidthRequest="300" FontSize="Small"/>
<StackLayout Orientation="Horizontal">
<Label Text="Registro em Produção: " TextColor="Black" FontSize="Small" HorizontalOptions="Start"
VerticalOptions="StartAndExpand" />
<DatePicker DateSelected="DataSelecionada" HorizontalOptions="Start" VerticalOptions="StartAndExpand">
<DatePicker.Format>dd/MM/yyyy</DatePicker.Format>
</DatePicker>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Registro em Produção: " TextColor="Black" FontSize="Small" HorizontalOptions="Center"
VerticalOptions="StartAndExpand" />
<Switch IsToggled="False" Toggled="RegistrarProducao" HorizontalOptions="Center"
VerticalOptions="StartAndExpand" />
</StackLayout>
<Button HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" HeightRequest="40" Text="Registrar Título"
Clicked="btnAdicionar_Clicked" FontSize="Small"/>
</StackLayout>
</StackLayout>
</ContentPage>
In RegistroBoletoService:
public string RegistrarBoleto(DadosTitulo dadosTitulo)
{
var data = JsonConvert.SerializeObject(dadosTitulo);
return data;
}
data allways return “{}”:
I have made a test calling RegistroBoletoService from Console Project, in the same Solution, and the result was as expected: data contains json
The interesting point that I noticed: when I have instantiated the class in MainPage.xaml.cs the behavior was diferent from Console Project, with Non-Public Members in the class:
Console Instantiate:
I think that this is the problem, anyone have an idea what is it happening ? Why when I have instantiated the class in the MainPage I get different behavior from the Console ?
Thanks a lot and sorry my English.
PS.: Project in .NET Standard; I’m not using MVVM in this case; I tried testing with the linker SDK Assemblies Only and None.

Resources