Goodmorning all .I am beginner in Xamarin.Forms. I am trying to learn how to get data in Listview with webservices.
My json format :
{
"contacts": [
{
"name": "Clark Kent",
"email": "mmguy#planet.com"
},
{ "name": "Bruce Wayne",
"email": "ceo#wayne.net"
},
{ "name": "Tony Stark",
"email": "playboy#stark.com"
},
]
}
I want to get this Data in Listview. Please help How to call Url and this data in Listview. Thanks in advance.
Just deserialize your json data and bind that deserialized json data to your listview.
xaml.cs page:
IEnumerable<ContactModel> contactList {get; set;}
contactList = JsonConvert.DeserializeObject<IEnumerable<ContactModel>>(json);
var listView = new ListView();
listView.ItemsSource =contactList;
xaml page:
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<Label Text="name"/>
<Label Text="email"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Related
I have 2 ContentView in MyWordPage.Xaml which are MyWordListView and AddWordsView
My MyWordPage.Xaml looks like this :
<ContentView x:Name="MyWordListView" >
<CollectionView x:Name="ListOfWords" IsVisible="False"
SelectionMode="Single" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding .}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentView>
<ContentView IsVisible="False" x:Name="AddWordsView" />
<pv:PancakeView HorizontalOptions="End" VerticalOptions="End" Margin="0,0,10,150" Padding="10" CornerRadius="10">
<Image HeightRequest="30" WidthRequest="30" Aspect="AspectFit" />
<pv:PancakeView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnChangeViewButton" />
</pv:PancakeView.GestureRecognizers>
</pv:PancakeView>
<Grid/>
If MyWordListView is visible, AddWordsView is not visible and vise versa.
The App starts with MyWordListPage visible and MyWordPage.xaml.cs looks like this:
public MyWordPage()
{
InitializeComponent();
// My second content view AddWordsView take content form a content page
// this content page name is MyAddWordPage
AddWordsView.Content = new MyAddWordPage().Content;
//My list of words
ListOfWords.ItemsSource = new List<string>()
{
"New York",
"London",
"Mumbai",
"Chicago"
};
}
//I navigate between the 2 View With an Overlay Button that make
//each one of View visible thanks to a boolean
bool ViewChange=false;
void OnChangeViewButton(System.Object sender, System.EventArgs e)
{
if (ViewChange==false)
{
AddWordsView.IsVisible=true;
MyWordListView.IsVisible=false;
ViewChange=!ViewChange;
}
else
{
AddWordsView.IsVisible=false;
MyWordListView.IsVisible=true;
ViewChange=!ViewChange;
}
}
OnUpdateMyList()
{
// Here I do things to refresh my list
}
MyAddWordPage.xaml.cs looks like this :
public MyWordPage()
{
InitializeComponent();
}
void OnInsertWord(System.Object sender, System.EventArgs e)
{
}
What I would like to do :
In MyAddWordPage.xaml.cs when clicking on a button to launch the function OnInsertWord() I would like to launch the function OnUpdateMyList() in MyWordPage.xaml.cs in order to refresh My collectionView in MyWordListView
Thanks for your help
According to your requirement, you can achieve this by overriding OnAppearing method.
The OnAppearing method is executed after the ContentPage is laid out, but just before it becomes visible.So, you can rebind the list to the collectionview in this method. Therefore, this is a good place to set the content of Xamarin.Forms views.
Here is the code in MyWordPage.xaml.cs:
public MainPage()
{
InitializeComponent();
// My second content view AddWordsView take content form a content page
// this content page name is MyAddWordPage
AddWordsView.Content = new MyAddWordPage().Content;
//My list of words
}
//Create a list
List<string> list = new List<string>()
{
"New York",
"London",
"Mumbai",
"Chicago"
};
protected override void OnAppearing()
{
base.OnAppearing();
ListOfWords.ItemsSource = list;
}
//I navigate between the 2 View With an Overlay Button that make
//each one of View visible thanks to a boolean
bool ViewChange = false;
void OnChangeViewButton(System.Object sender, System.EventArgs e)
{
if (ViewChange == false)
{
AddWordsView.IsVisible = true;
MyWordListView.IsVisible = false;
ViewChange = !ViewChange;
}
else
{
AddWordsView.IsVisible = false;
MyWordListView.IsVisible = true;
ViewChange = !ViewChange;
}
}
}
Here is the code in MyWordPage.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="App5.MainPage">
<StackLayout>
<StackLayout x:Name="MyWordListView">
<CollectionView x:Name="ListOfWords" SelectionMode="Single" >
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout >
<Label Text="{Binding .}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
<ContentView IsVisible="False" x:Name="AddWordsView" >
<Label Text="Here is the text."></Label>
</ContentView>
<StackLayout>
<Button Clicked="OnChangeViewButton"></Button>
</StackLayout>
</StackLayout>
</ContentPage>
Im working with the ListView component and I would like to set categories which makes use of the Header within a ListView.
The content I have is a list of events that are happening today, tomorrow and the next day
How would I go about adding that to a list
My code so far is below
<ListView>
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Event 1 - Today</x:String>
<x:String>Event 2 - Today</x:String>
<x:String>Event 3 - Today</x:String>
<x:String>Event 4 - Today</x:String>
<x:String>Event 1 - Tomorrow</x:String>
<x:String>Event 2 - Tomorrow</x:String>
<x:String>Event 3 - Tomorrow</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.Header>
<Label Text="Today"/>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding}" Style="{StaticResource listViewRacecourse}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I just have no clue how to get two values within the array, and then split them into two groups using ListView headers.
This is just a POC so I don't have a DB with all the content, hence not using a API or connection to a DB.
About ListView Group, Jason have provided one article about detailed info. If you still have some problem, you can also take a look the following sample.
Firstly, create class to hold event info.
public class eventmodel
{
public string eventname { get; set; }
}
Then, a way to group the data, with a heading for each list.
public class eventlist:List<eventmodel>
{
public string heading { get; set; }
public List<eventmodel> events => this;
}
Finally, using Observablecollection to bind to listview. Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
public class eventgroup
{
public ObservableCollection<eventlist> eventgroups { get; set; }
public eventgroup()
{
eventgroups = new ObservableCollection<eventlist>();
var list1 = new eventlist()
{
new eventmodel() { eventname= "Event 1 - Today" },
new eventmodel() { eventname= "Event 2 - Today" },
new eventmodel() { eventname= "Event 3 - Today" },
new eventmodel() { eventname= "Event 4 - Today" }
};
list1.heading = "Today";
var list2 = new eventlist()
{
new eventmodel() { eventname= "Event 1 - Tomorrow" },
new eventmodel() { eventname= "Event 2 - Tomorrow" },
new eventmodel() { eventname= "Event 3 - Tomorrow" },
new eventmodel() { eventname= "Event 4 - Tomorrow" }
};
list2.heading = "Tomorrow";
eventgroups.Add(list1);
eventgroups.Add(list2);
}
}
ListView displaying data.
<ListView IsGroupingEnabled="true" ItemsSource="{Binding eventgroups}">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<Label BackgroundColor="Red" Text="{Binding heading}" />
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding eventname}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public partial class Page6 : ContentPage
{
public Page6()
{
InitializeComponent();
this.BindingContext = new eventgroup();
}
}
The screenshot:
I am new to xamarin and trying to display a listview. My attempt is as follows.
<ContentPage.Content>
<StackLayout>
<ListView x:Name="ComListView" RowHeight="80">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid Margin="8">
<Label Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Text="hello world" FontAttributes="Bold" />
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
But when I ran the app, even I navigate to correct page; nothing display. For any other views, it will display the right output. So where could I get wrong on the listview?
You have to put items to the ListView. Currently, you only specify the ItemTemplate, which determines how an item will look (in your case, they will all look the same (i.e. Labels with 'hello world' text)). But the ListView is empty and so there are no items to show.
You can set items using the ItemsSource property of the ListView.
Usually, you use Binding inside an ItemTemplate to show item content.
Let's say we have a class Person:
class Person
{
public string Name { get; set; }
}
Then you create a List of Person objects and add it to your ListView in code:
var personnel = new List<Person>
{
new Person { Name = "Booker" },
new Person { Name = "Elizabeth" }
};
ComListView.ItemsSource = personnel;
And in your XAML, you have to set the ItemTemplate so that it shows the Name of each Person:
<Label Text="{Binding Name, Mode=OneWay}" />
Note: You can also bind to ItemsSource from XAML if you have a ViewModel.
You are not binding the data to the listview.
use the ItemSource property to bind data, either from xaml, code behind or use a binding to populate from your ViewModel
I have been developing a xamarin hybrid app. I have a content page with a button and I want to load a list view inside the content page on click event of the button.Function to get data from API
public static async Task<List<TranslationWords>> GetTranslation()
{
string url = "";//api url here
dynamic results = await DataService.GetDataFromService(url).ConfigureAwait(false);
if (results != null)
{
var wordsList = JsonConvert.DeserializeObject<List<TranslationWords>>(results);
Console.WriteLine(wordsList);
return wordsList;
}
else
{
return null;
}
public static async Task<List<dynamic>> GetDataFromService(string url)
{
HttpClient client = new HttpClient();
var json = "{'word':'wide','type':'eng_to_tam'}";
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
dynamic data = null;
if (response != null)
{
string res = response.Content.ReadAsStringAsync().Result;
data = JsonConvert.DeserializeObject(res);
return data;
} else {
//code to handle null response
}
}
code for master page detail xaml
<ContentPage.Content>
<StackLayout Padding="10">
<Switch HorizontalOptions="Start" VerticalOptions="Start" Toggled="Switcher_Toggled"></Switch>
<Label Text="Enter a Word:" />
<Entry x:Name="wordToFind" Text="" />
<Button x:Name="searchButton" Text="Search" Clicked="Load_List"/>
<ContentView x:Name="MainPageContainer"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
/>
</StackLayout>
</ContentPage.Content>
list view xaml
The list view is placed inside a content view(MainPageContainer) in the main page.Content view will be loaded with data when the button in master detail page is clicked
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
Padding="10">
<Label
Text="{Binding TamilWord}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Label
Text="{Binding TamilMeaning}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemDetailTextStyle}"
FontSize="13" />
<Label
Text="{Binding EnglishTranslation}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemDetailTextStyle}"
FontSize="13" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
data binding in .cs file
public List<TranslationWords> Words;
public TransList ()
{
InitializeComponent ();
Words = Core.GetTranslation().Result; //method to get data from api
transListView.ItemsSource = Words;
}
Probably the simplest way is to set the IsVisible to False and in your on click event to True. If "load" means "show".
Your 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:XFIntro"
x:Class="XFIntro.MainPage">
<StackLayout>
<Button Text="Click" Clicked="ListClicked" />
<ListView x:Name="LView" IsVisible="False"/>
</StackLayout>
</ContentPage>
The Code Behin
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
LView.ItemsSource = new List<string>() { "foo", "bar", "baz"};
}
void ListClicked(object sender, EventArgs e)
{
LView.IsVisible = true;
}
}
If load means you want to load items onto the listview with the click event, the code is nearly the same, just use
LView.ItemsSource = new List<string>() { "foo", "bar", "baz"};
in your click event now and set the ListView always to visible
Nested list view is not working, I have a list which contains another list in it. To show it in View I am using Nested listview; But the code is not working,and i am not able to identify on where it went wrong... Below is my code
Main Page
<ContentPage.Content>
<StackLayout>
<ListView x:Name="outerListview" ItemsSource="{Binding lst}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="outerListviewCell">
<ViewCell.View>
<ContentView>
<Label Text="{Binding ItemName}"/>
<StackLayout>
<ListView ItemsSource="{Binding ItemList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="InnerListviewCell">
<Grid>
<Label Text="{Binding stockQty}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
ViewModel
public MainPageViewModel()
{
lst = new ObservableCollection<A>()
{
new A()
{
ItemName="Item1", ItemList=new ObservableCollection<ItemDetails>()
{
new ItemDetails() { stockQty="2"},
new ItemDetails(){ stockQty="3"}
}
},
new A()
{
ItemName="Item2", ItemList=new ObservableCollection<ItemDetails>()
{
new ItemDetails() { stockQty="3"},
new ItemDetails(){ stockQty="4"}
}
}
};
}
Model ( Class A and Class Itemdetails)
class A:INotifyPropertyChanged
{
public A()
{
ItemName = string.Empty;
ItemList = new ObservableCollection<ItemDetails>();
}
private string _ItemName;
public string ItemName
{
get { return _ItemName; }
set { _ItemName = value; OnPropertyChanged(); }
}
private ObservableCollection<ItemDetails> _itemlist;
public ObservableCollection<ItemDetails> ItemList
{
get { return _itemlist; }
set { _itemlist = value; OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
class ItemDetails:INotifyPropertyChanged
{
private string _stockQty;
public string stockQty
{
get { return _stockQty; }
set { _stockQty = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
When I Run the above code I am getting below output in screen
2
3
What is expected actually is
Item1
2
3
Item2
3
4
What is wrong in above code? could anyone can help me?
Nesting Listview inside another Listview is not a good idea and it is not a supported on Xamarin.Forms.
ListView is very "sensitive" and it can easialy cause problems with scrolling and of course there are problems with poor performance of your app.
So I strongly recommend you to rethink about your layout and take a look at Grouping with ListView more about it here, maybe you can achieve what you want with Grouping.
After checking your code , I found something need to modify in your code.
In order to show the ItemName , you should wrap Label inside StackLayout .
In order to get Uneven Row, you should set listview.HasUnevenRows = true.
Modify your code as below:
<ContentPage.Content>
<ListView x:Name="outerListview" HasUnevenRows="True" ItemsSource="{Binding lst}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="outerListviewCell">
<ViewCell.View>
<ContentView>
<StackLayout>
<Label Text="{Binding ItemName}"/>
<ListView ItemsSource="{Binding ItemList}" RowHeight="20">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="InnerListviewCell">
<Grid>
<Label Text="{Binding stockQty}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
That is absolutely wrong. You must use one ListView with IsGroupingEnabled set to True.
Follow instuctions here to make it work correct: https://xamarinhelp.com/xamarin-forms-listview-grouping/