Problem with Xamarin app while calling an API - c#

I'm a beginner with C# and whole .NET (just wanted to mention at the beginning). So I'm learning Xamarin and APIs.
I've got the problem with fetching some data from API (https://jsonplaceholder.typicode.com/posts) to display inside the app. Once I execute the app, it gives me an error:
System.InvalidCastException: 'Specified cast is not valid'.
I also don't see where is it failing (after error, exception window is blank - like not showing where it stops).
using ExerciseApp.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using Xamarin.Forms;
namespace ExerciseApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
GetPosts();
}
private async void GetPosts()
{
HttpClient client = new HttpClient();
var response = await client.GetStringAsync("https://jsonplaceholder.typicode.com/posts");
var posts = JsonConvert.DeserializeObject<List<Posts>>(response);
PostsListView.ItemsSource = posts;
}
}
}
<?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="ExerciseApp.MainPage">
<StackLayout BackgroundColor="White">
<Frame BackgroundColor="#581845" Padding="10" CornerRadius="5" Margin="25">
<Label Text="ʕ•ᴥ•ʔ" HorizontalTextAlignment="Center" TextColor="White" FontSize="30"/>
</Frame>
<Label Text="Welcome to Exercise app with RESTAPI and NHibernate" TextColor="#581845" FontSize="Title" Padding="10" HorizontalTextAlignment="Center"/>
<Label FontSize="20" Padding="20" HorizontalTextAlignment="Center" TextColor="#581845">
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="Here we will load some data"/>
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
<ListView x:Name="PostsListView">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding id}" TextColor="#581845"></Label>
<Label Text="{Binding title}" TextColor="#581845"></Label>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
namespace ExerciseApp.Models
{
public class Posts
{
public int userId { get; set; }
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
}
}

ListView must use a Cell type in their template. Adding a ViewCell into your XAML will fix this problem
<ListView x:Name="PostsListView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding id}" TextColor="#581845"></Label>
<Label Text="{Binding title}" TextColor="#581845"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
alternately, you can use a CollectionView which allows you to create templates without the restriction of using a Cell

Related

delete cell from listview and database fire base in xamarin forms

I have a list view which contains cells like this :
<StackLayout Orientation="Horizontal" Margin="30,0,20,0" VerticalOptions="Center">
<Label Grid.Row="0" Text="{Binding AppointmentPatientName}" VerticalOptions="Center" HorizontalOptions="StartAndExpand" Style="{StaticResource labelView}"/>
<Label Grid.Row="0" Grid.Column="2" Text="{Binding AppointmentDate.Date}" Font="Small" HorizontalOptions="CenterAndExpand" Style="{StaticResource labelView}" />
<Label x:Name="Delete Button" Text="X"></Label>
</StackLayout>
How can I activate this label in order to make it Delete from firebase database it's smth like this :
private async void ItemImageButton_Clicked(object sender, EventArgs e)
{
var appoitment = (Appoitment)((ImageButton)sender).CommandParameter;
AppintmentService appintmentService = new AppintmentService();
await appintmentService.DeleteFollowup(appoitment.PatientID, appoitment.ID);
await DisplayAlert("Delted", "The patient Deleteed", "Ok");
await Navigation.PushAsync(new PatientProfileFollowUpPage());
}
but i want it for label not ImgButton and want activate it in viewmodel page
i want it for label not ImgButton and want activate it in viewmodel
page
Yes, you can use TapGestureRecognizer and MVVM to achieve this.
Based on your code ,I made a simple demo.You can refer to the following code:
<ContentPage.BindingContext>
<tapapp1:MyViewModel></tapapp1:MyViewModel>
</ContentPage.BindingContext>
<StackLayout Orientation="Horizontal" Margin="30,0,20,0" VerticalOptions="Center">
<Label Text="{Binding AppointmentPatientName}" VerticalOptions="Center" HorizontalOptions="StartAndExpand" />
<Label Grid.Column="2" Text="{Binding AppointmentDate}" Font="Small" HorizontalOptions="CenterAndExpand" />
<Label x:Name="Delete" Text="X" >
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding TapCommand}"
/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
MyViewModel.cs
public class MyViewModel
{
public string AppointmentPatientName { get; set; }
public string AppointmentDate { get; set; }
public ICommand TapCommand => new Command(RemoveItem);
private void RemoveItem()
{
// add your code here
}
public MyViewModel()
{
AppointmentPatientName = "Test1";
AppointmentDate = "2022-4-28";
}
}
Note: You can modify above code based on your requirement.

Display everything from specific value inside child - Xamarin Firebase

I have the following firebase database:
And let's say I want to display all the values inside "Rest1". How can I do it?
I currently use the following code to make the connection and display everything inside the database.
display.xaml.cs
public ObservableCollection<MyDatabaseRecord> DatabaseItems { get; set; } = new
ObservableCollection<MyDatabaseRecord>();
FirebaseClient firebaseClient = new FirebaseClient("link");
private void tabelaRestLoad()
{
var collection = firebaseClient
.Child("Menus")
.AsObservable<MyDatabaseRecord>()
.Subscribe((dbevent) =>
{
if (dbevent != null)
{
DatabaseItems.Add(dbevent.Object);
}
});
}
display.xaml:
<StackLayout Margin="15,0,15,5" BackgroundColor="Transparent">
<CollectionView ItemsSource="{Binding DatabaseItems}" SelectionMode="Single" SelectionChanged="OnCollectionViewSelectionChanged" BackgroundColor="Transparent">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame BackgroundColor="#fff2d8" HorizontalOptions="Center" Margin="0,10,0,5" Padding="2" WidthRequest="350" CornerRadius="10">
<StackLayout BackgroundColor="#fff2d8">
<Label Text="{Binding Plate1}" TextColor="Black" FontAttributes="Bold" HorizontalOptions="Center" Margin="0, 5, 0, 0" FontSize="20"/>
<Label Text="{Binding Plate2}" TextColor="Black" HorizontalOptions="Center" Margin="0, 0, 0, 15" FontSize="17"/>
<Label Text="{Binding Plate3}" TextColor="Black" Margin="10, 0, 0, 0" FontSize="15"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
MyDatabaseRecord.cs:
public class MyDatabaseRecord
{
public string Plate1 { get; set; }
public string Plate2 { get; set; }
public string Plate3 { get; set; }
}
As I said, this code I'm using returns every "Plate" value from both Rest1 and Rest2 inside "Menus" child. My question here is, how can I only display the values inside Rest1, for example, instead of all of them?
Thanks in advance
The minimal code change would be to use a query on the key:
var collection = firebaseClient
.Child("Menus")
.OrderByKey()
.EqualTo("Rest1")
.AsObservable<MyDatabaseRecord>()
...

Xamarin.Forms - Binding a command

I am using ToolKits Expander and I am trying to bind a command, this is what I got so far:
public partial class AssignTaskPage : ContentPage
{
public AssignTaskPage()
{
InitializeComponent();
GetMathSubCatgories = new Command(() => MathSubCatgoriesCommand());
}
public ICommand GetMathSubCatgories { get; private set; }
void MathSubCatgoriesCommand()
{
Console.Write("Here");
}
}
And in my view
<xct:Expander Command="{Binding GetMathSubCatgories}">
<xct:Expander.Header>
<Frame Padding="10" Margin="10" HasShadow="False" BorderColor="LightGray" VerticalOptions="CenterAndExpand">
<StackLayout Orientation="Horizontal">
<Image Source="{Binding icon}" WidthRequest="25" HeightRequest="25"></Image>
<Label Text="{Binding name}" TextColor="{Binding textColor}" FontSize="Large" FontAttributes="Bold" HeightRequest="35" VerticalOptions="CenterAndExpand"></Label>
</StackLayout>
</Frame>
</xct:Expander.Header>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListView x:Name="SubCategories" ItemsSource="{Binding subCategories}" ItemSelected="SubCategories_ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding name}" TextColor="#02cc9d" FontAttributes="Bold" HeightRequest="35" VerticalOptions="CenterAndExpand"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</xct:Expander>
This does not work at all, (I put a break point on Console.Write("Here"); and its not hitting it)
So I did some digging and found this tutorial:
https://www.syncfusion.com/kb/12154/how-to-bind-command-to-expander-in-itemtemplate-of-xamarin-forms-listview-sflistview
and here is the sample in git.
https://github.com/SyncfusionExamples/command-to-expander-in-itemtemplate-listview-xamarin
I understand what I have to do here, the problem I am facing is when this Command is called, I was looking to get a value and use it in my AssignTaskPage, but what the tutorial is saying to have a ViewModel which is in a separate file. So should I setup a MessagingCenter in my AssignTaskPage and call it in the ViewModel to get the value I want and pass it to AssignTaskPage?
Because your command isn't defined in the ViewModel that you're binding to.You could bind the command which is defined in your AssignTaskPage,and then bind the viewmodel for the parent element of the expander.
For example :
public partial class AssignTaskPage : ContentPage
{
public AssignTaskPage()
{
InitializeComponent();
GetMathSubCatgories = new Command(() => MathSubCatgoriesCommand());
BindingContext = this;
}
public ICommand GetMathSubCatgories { get; private set; }
void MathSubCatgoriesCommand(object obj)
{
DisplayAlert("Alert!", "" + (obj as Contact).ContactName + "expanded", "Ok");
}
}
the xaml (here use the xaml codes of the above sample),the grid bind the viewmodel,and your expander bind the command of the root (your 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:local="clr-namespace:ExpanderXamarin"
x:Class="ExpanderXamarin.ExpandableListView"
x:Name="root"
xmlns:sflistview="clr-namespace:Syncfusion.ListView.XForms;assembly=Syncfusion.SfListView.XForms"
xmlns:expander="clr-namespace:Syncfusion.XForms.Expander;assembly=Syncfusion.Expander.XForms">
<ContentPage.Content>
<Grid x:Name="mainGrid" BackgroundColor="#F0F0F0" Padding="4">
<Grid.BindingContext>
<local:ViewModel />
</Grid.BindingContext>
<sflistview:SfListView x:Name="listView" AutoFitMode="DynamicHeight" ItemsSource="{Binding ContactsInfo}">
<sflistview:SfListView.ItemTemplate>
<DataTemplate>
<Frame x:Name="frame" CornerRadius="2" Padding="{OnPlatform Android=1, iOS=1, UWP=0}" Margin="{OnPlatform Android=1, iOS=1, UWP=0}" OutlineColor="White" HasShadow="{OnPlatform Android=true, iOS=false, UWP=true}">
<Grid Padding="{OnPlatform Android=2, iOS=2, UWP=0}" Margin="{OnPlatform Android=1, iOS=1, UWP=0}" BackgroundColor="White" >
<expander:SfExpander x:Name="expander" HeaderIconPosition="None">
<expander:SfExpander.Behaviors>
<local:EventToCommandBehavior Command="{Binding Path=BindingContext.GetMathSubCatgories, Source={x:Reference root}}" EventName="Expanding" CommandParameter="{Binding .}"/>
</expander:SfExpander.Behaviors>
<expander:SfExpander.Header>
...
</expander:SfExpander.Header>
<expander:SfExpander.Content>
..
</expander:SfExpander.Content>
</expander:SfExpander>
</Grid>
</Frame>
</DataTemplate>
</sflistview:SfListView.ItemTemplate>
</sflistview:SfListView>
</Grid>
</ContentPage.Content>
</ContentPage>
if you want get the parameters you could bind the CommandParameter like above.

How to get symbol and price to show individually in a listview on xamarin c#

How to get symbol in one label and the price in another label in xamrain c#
What i need help on is how i can make the symbol and the price be together in a listview for all the different coins. You can see in the link under GetPrice different symbols and different prices. I just want to put them in groups and seperate them in a listview. Please help me.
This is my 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"
x:Class="Crypto_Portfolio.MainPage">
<StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="Start">
<ListView x:Name="priceList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding symbol}" />
<Label Text="{Binding price}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="End">
<Button Clicked="priceClick" Text="Fetch Price" HorizontalOptions="CenterAndExpand" VerticalOptions="End"/>
</StackLayout>
</StackLayout>
</ContentPage>
This is my MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Xamarin.Forms;
namespace Crypto_Portfolio
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
GetPrice();
}
public class Crypto
{
public string symbol { get; set; }
public string price { get; set; }
}
private async void GetPrice()
{
HttpClient client = new HttpClient();
var response = await client.GetStringAsync("https://api.binance.com/api/v3/ticker/price");
var cryptoconverted = JsonConvert.DeserializeObject<List<Crypto>>(response);
priceList.ItemsSource = cryptoconverted;
}
void priceClick(object sender, EventArgs e)
{
GetPrice();
}
}
}
first, you need to deserialize the json from the webservice into a C# class. You can use json2csharp.com to to this
public class Stock
{
public string symbol { get; set; }
public string price { get; set; }
}
then in your GetPrice method
var response = await client.GetStringAsync("https://api.binance.com/api/v3/ticker/price");
var stocks = JsonConvert.DeserializeObject<List<Stock>>(response);
next, add a ListView to your XAML
<ListView x:Name="stockList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding symbol}" />
<Label Text="{Binding price}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
finally, assign your data to the ListView in GetPrice
stockList.ItemsSource = stocks

How to access nested label via C#?

How to access ListViews item template element named TextButtonDetails to update its Text property?
i tried so -
TextButtonDetails.Text = AppResources.AppResources.MoreDetailsProduct;
and so
listView.FindByName<Label>("TextButtonDetails").Text = AppResources.AppResources.MoreDetailsProduct;
<ListView x:Name="listView" HorizontalOptions="FillAndExpand" HasUnevenRows="true" VerticalScrollBarVisibility="Default" Refreshing="Refresh" ItemSelected="Details">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Margin="20" VerticalOptions="StartAndExpand" Orientation="Vertical">
<Label Text="{Binding Title}" FontAttributes="Bold" VerticalTextAlignment="Start" HorizontalOptions="StartAndExpand" />
<Label Text="{Binding Text}" VerticalOptions="StartAndExpand" />
<Label VerticalTextAlignment="End" TextColor="#2196F3" x:Name="TextButtonDetails"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can set your resource value in your view model:
public class YourItemViewModel
{
public YourItemViewModel()
{
Title = ...
Text = ...
MoreDetailsLabel = AppResources.AppResources.MoreDetailsProduct;
}
public string Title { get; }
public string Text { get; }
public string MoreDetailsLabel { get; }
}
or use the TranslateExtension markup extension from the xamarin forms docs: https://learn.microsoft.com/en-US/xamarin/xamarin-forms/app-fundamentals/localization/text?tabs=windows#localizing-xaml
It's a good idea to support localization.
You will be able to reference your resource value directly like this:
<?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="UsingResxLocalization.FirstPageXaml"
xmlns:i18n="clr-namespace:UsingResxLocalization;assembly=UsingResxLocalization">
<StackLayout Padding="0, 20, 0, 0">
<Label Text="{i18n:Translate NotesLabel}" />
<Entry Placeholder="{i18n:Translate NotesPlaceholder}" />
<Button Text="{i18n:Translate AddButton}" />
</StackLayout>
</ContentPage>

Categories

Resources