I have created a WCF service and publish into the cloud in http://kailun92wcf.cloudapp.net/Service1.svc. How can I use the method of getSearchCoords to get all the names out and display it into a list ? One example tested result is display below.
"{\"SearchResults\":[{\"PageCount\":\"1\"},{\"SEARCHVAL\":\"ORCHARD 22\",\"CATEGORY\":\"Buildin" +
"g\",\"X\":\"29483.4267\",\"Y\":\"31269.938\"},{\"SEARCHVAL\":\"ORCHARD BEL AIR\",\"CATEGORY\":\"" +
"Building\",\"X\":\"27071.2616\",\"Y\":\"31629.2465\"},{\"SEARCHVAL\":\"ORCHARD BOULEVARD\",\"C" +
"ATEGORY\":\"CATC\",\"X\":\"27614.8046\",\"Y\":\"31857.4392\"},{\"SEARCHVAL\":\"ORCHARD BUILDIN" +
"G\",\"CATEGORY\":\"Building\",\"X\":\"28449.6799\",\"Y\":\"31527.587\"},{\"SEARCHVAL\":\"ORCHARD" +
" BUILDING (FRIENDLY BUILDINGS)\",\"CATEGORY\":\"Community\",\"X\":\"28448.5715\",\"Y\":\"315" +
"26.146\"},{\"SEARCHVAL\":\"ORCHARD BUILDING (WIRELESS HOTSPOTS)\",\"CATEGORY\":\"Recreat" +
"ion\",\"X\":\"28448.3426\",\"Y\":\"31525.9693\"},{\"SEARCHVAL\":\"ORCHARD CENTRAL\",\"CATEGORY" +
"\":\"Building\",\"X\":\"28709.3453\",\"Y\":\"31452.9157\"},{\"SEARCHVAL\":\"ORCHARD CENTRAL (F" +
"RIENDLY BUILDINGS)\",\"CATEGORY\":\"Community\",\"X\":\"28709.3453\",\"Y\":\"31452.9157\"},{\"" +
"SEARCHVAL\":\"ORCHARD CENTRAL (WIRELESS HOTSPOTS)\",\"CATEGORY\":\"Recreation\",\"X\":\"28" +
"709.3453\",\"Y\":\"31452.9156\"},{\"SEARCHVAL\":\"ORCHARD CINELEISURE (WIRELESS HOTSPOTS" +
")\",\"CATEGORY\":\"Recreation\",\"X\":\"28347.9192\",\"Y\":\"31538.4923\"},{\"SEARCHVAL\":\"ORCH" +
"ARD COURT\",\"CATEGORY\":\"Building\",\"X\":\"28931.3725\",\"Y\":\"31225.6489\"},{\"SEARCHVAL\"" +
":\"ORCHARD CREDIT AUTO HOUSE\",\"CATEGORY\":\"Building\",\"X\":\"23255.1398\",\"Y\":\"35016.5" +
"269\"},{\"SEARCHVAL\":\"ORCHARD EMERALD (GREEN MARK BUILDINGS)\",\"CATEGORY\":\"Environm" +
"ent\",\"X\":\"28617.7255\",\"Y\":\"31549.8898\"},{\"SEARCHVAL\":\"ORCHARD FOUNTAIN CORNER\",\"" +
"CATEGORY\":\"Building\",\"X\":\"28464.8743\",\"Y\":\"31580.3349\"},{\"SEARCHVAL\":\"ORCHARD GA" +
"TEWAY\",\"CATEGORY\":\"Building\",\"X\":\"28666.655\",\"Y\":\"31427.7293\"},{\"SEARCHVAL\":\"ORC" +
"HARD GATEWAY # EMERALD\",\"CATEGORY\":\"Building\",\"X\":\"28617.699\",\"Y\":\"31549.9633\"}," +
"{\"SEARCHVAL\":\"ORCHARD GRAND COURT PTE LTD (FRIENDLY BUILDINGS)\",\"CATEGORY\":\"Comm" +
"unity\",\"X\":\"28580.4218\",\"Y\":\"31071.6324\"},{\"SEARCHVAL\":\"ORCHARD HOTEL (FRIENDLY " +
"BUILDINGS)\",\"CATEGORY\":\"Community\",\"X\":\"27469.037\",\"Y\":\"32216.2037\"},{\"SEARCHVAL" +
"\":\"ORCHARD HOTEL (WIRELESS HOTSPOTS)\",\"CATEGORY\":\"Recreation\",\"X\":\"27469.0369\",\"" +
"Y\":\"32216.2037\"},{\"SEARCHVAL\":\"ORCHARD HOTEL GALLERIA\",\"CATEGORY\":\"Building\",\"X\"" +
":\"27494.5279\",\"Y\":\"32195.9069\"}]}"
I have to use the above result to display all the name into a listbox in windows phone 7.1. How can I do that ?
I have saw from other sources they had this to display names into a list box in windows phone 7.1:
private void Search_Click(object sender, RoutedEventArgs e)
{
//retrieving the results for the keywords the user input
searchError.Text = "Loading... Please Wait";
if (Classes.Global.searched == 1)
{
searchVal = new List<string>();
}
MobileClinicWebService.MCWebServiceSoapClient obj = new MobileClinicApp.MobileClinicWebService.MCWebServiceSoapClient();
obj.getSearchCoordsAsync(searchBar.Text.ToString());
obj.getSearchCoordsCompleted += new EventHandler<MobileClinicWebService.getSearchCoordsCompletedEventArgs>(obj_getSearchCoordsCompleted);
}
void obj_getSearchCoordsCompleted(object sender, MobileClinicWebService.getSearchCoordsCompletedEventArgs e)
{
//retrieving the results, and displaying it on the phone
string[] search = null;
if (!e.Result.ToString().Equals("error"))
{
using (JsonTextReader jsonReader = new JsonTextReader(new StringReader(e.Result)))
{
while (jsonReader.Read())
{
if ((string)jsonReader.Value == "SEARCHVAL")
{
jsonReader.Read();
searchVal.Add((string)jsonReader.Value);
}
if ((string)jsonReader.Value == "X")
{
jsonReader.Read();
posx.Add(Double.Parse(jsonReader.Value.ToString()));
}
if ((string)jsonReader.Value == "Y")
{
jsonReader.Read();
posy.Add(Double.Parse(jsonReader.Value.ToString()));
}
}
}
search = new string[searchVal.Count];
for (int i = 0; i < searchVal.Count; i++)
{
search[i] = searchVal[i];
}
}
else
{
searchError.Text = "No Results Found";
}
if (search != null)
{
Classes.Global.searched = 1;
searchError.Text = "Search Results";
Results.ItemsSource = search;
}
}
First and foremost, since you control the structure of your json response at the web service source, you should fix its structure.
From your data, Search result contains a page results count and a set of results, hence I have changed the json to reflect this. This implies that Parsing with a suitable json de-serializer is possible and makes your code compact and tidy. Ensure you have the Newtonsoft json library set up in your project.
C# Classes
public class ResultSetPager<T>
{
public int PageCount { get; set; }
public IEnumerable<T> SearchResults { get; set; }
}
public class Place
{
public string SearchVal { get; set; }
public string Category { get; set; }
public double X { get; set; }
public double Y { get; set; }
}
Click event
private void LoadJsonData(object sender, RoutedEventArgs e)
{
string data = #"{
""PageCount"" : ""1"",
""SearchResults"": [
{
""SEARCHVAL"": ""ORCHARD22"",
""CATEGORY"": ""Building"",
""X"": ""29483.4267"",
""Y"": ""31269.938""
},
{
""SEARCHVAL"": ""ORCHARDBELAIR"",
""CATEGORY"": ""Building"",
""X"": ""27071.2616"",
""Y"": ""31629.2465""
}
]
}";
var pagedResults = JsonConvert.DeserializeObject<ResultSetPager<Place>>(data);
lstPlaces.ItemsSource = pagedResults.SearchResults;
}
Xaml
<Grid>
<StackPanel>
<Button Click="LoadJsonData" Content="Test"></Button>
<ListBox x:Name="lstPlaces">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0 0 0 15">
<TextBlock Text="{Binding SearchVal}" FontSize="{StaticResource PhoneFontSizeLarge}" />
<TextBlock Text="{Binding Category}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
Related
I have a lazy loading in gridview whose data is taken from JSON.
Sample of JSON:
{
"error": false,
"total_data": 32,
"data_per_page": "16",
"current_page": 1,
"total_page": 2,
"current_total": 16,
"data": [
{
"id": "2613",
"judul": "Kamus ID EN",
"slug": "kamus-id-en",
"cover": "https://mhnkp2.com/src/umum/cover/kamus_ID_EN-thumb.jpg",
"path": "https://mhnkp2.com/school/dl/dodl/2613",
"ukuran": "3504835",
"formated_size": "3.34 MB",
"fname": "kamus_ID_EN.pdf",
"publish": "1",
"urgent": "400",
"kelas": "0",
"nama_kelas": "Umum"
},
XAML:
<Grid x:Name="content" Grid.Row="1" Loaded="MainGrid_Loaded">
<GridView
x:Name="itemGridView"
Loaded="itemGridView_Loaded">
<GridView.ItemTemplate>
<DataTemplate>
<Grid
Width="135"
Height="280"
Margin="5,5,5,5"
Background="White">
<TextBlock
x:Name="title"
Margin="0,0,10,10"
FontSize="14"
FontWeight="SemiBold"
Foreground="Black"
Style="{StaticResource TitleTextBlockStyle}"
Text="{Binding Judul}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Code:
ObservableCollection<Buku> datasource = new ObservableCollection<Buku>();
int offset = 0;
private void MainGrid_Loaded(object sender, RoutedEventArgs e)
{
itemGridView.ItemsSource = datasource;
Umum(1);
}
public class Buku
{
public string Judul { get; set; }
}
private async void Umum(int offset)
{
urlPath = "https://mhnkp2.com/school/api-v3/fetch/umum";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("halaman", offset.ToString()),
new KeyValuePair<string, string>("limit", "16"),
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
double total = groupObject1["total_data"].GetNumber();
double pages = groupObject1["total_page"].GetNumber();
double page = groupObject1["current_page"].GetNumber();
Buku file = new Buku();
file.PageNo = Convert.ToInt32(page);
file.Pages = Convert.ToInt32(pages);
file.Total = Convert.ToInt32(total);
JsonArray jsonData1 = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData1)
{
JsonObject groupObject2 = groupValue1.GetObject();
string title = groupObject2["judul"].GetString();
Buku file1 = new Buku();
file1.Judul = title;
datasource.Add(file1);
}
itemGridView.ItemsSource = datasource;
}
}
private void itemGridView_Loaded(object sender, RoutedEventArgs e)
{
ScrollViewer viewer = GetScrollViewer(this.itemGridView);
viewer.ViewChanged += Viewer_ViewChanged;
}
private void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
ScrollViewer view = (ScrollViewer)sender;
double progress = view.VerticalOffset / view.ScrollableHeight;
//Debug.WriteLine(progress);
if (progress > 0.7 && !incall && !endoflist)
{
incall = true;
busyindicator.IsActive = true;
Umum(++offset);
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
I am having a problem, that the gridview should display data on pages 1 and 2, but in the gridview the data displayed on page 2 is a repetition of data on page 1, as shown below:
How to fix it?
Note:
The page uses the "offset" parameter
The page limit is "total_page" in JSON
you just need to pass the offset value to MainGrid_Loaded and set offset zero to one
ObservableCollection<Buku> datasource = new ObservableCollection<Buku>();
int offset = 1; // set offset zero to one
private void MainGrid_Loaded(object sender, RoutedEventArgs e)
{
itemGridView.ItemsSource = datasource;
Umum(offset); // just change 1 to offset
}
public class Buku
{
public string Judul { get; set; }
}
private async void Umum(int offset)
{
urlPath = "mhnkp2.com/school/api-v3/fetch/ktsp2006/kelas/1";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("halaman", offset.ToString()),
new KeyValuePair<string, string>("limit", "16"),
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
double total = groupObject1["total_data"].GetNumber();
double pages = groupObject1["total_page"].GetNumber();
double page = groupObject1["current_page"].GetNumber();
Buku file = new Buku();
file.PageNo = Convert.ToInt32(page);
file.Pages = Convert.ToInt32(pages);
file.Total = Convert.ToInt32(total);
JsonArray jsonData1 = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData1)
{
JsonObject groupObject2 = groupValue1.GetObject();
string title = groupObject2["judul"].GetString();
Buku file1 = new Buku();
file1.Judul = title;
datasource.Add(file1);
}
itemGridView.ItemsSource = datasource;
}
}
private void itemGridView_Loaded(object sender, RoutedEventArgs e)
{
ScrollViewer viewer = GetScrollViewer(this.itemGridView);
viewer.ViewChanged += Viewer_ViewChanged;
}
private void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
ScrollViewer view = (ScrollViewer)sender;
double progress = view.VerticalOffset / view.ScrollableHeight;
//Debug.WriteLine(progress);
if (progress > 0.7 && !incall && !endoflist)
{
incall = true;
busyindicator.IsActive = true;
Umum(offset++);
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
I am doing a cross platform project in Xamarin (Android and iOS). I downloaded Xamarin.Forms.CarouselView and I'm getting an error:
Java.Lang.IllegalArgumentException: itemView may not be null
I've tried many ways to do this but a lot of the examples are in MVVM and I haven't converted the project to MVVM yet. I would like CarouselView to work first. I've already tried to different other nuget packages for CarouselView and got really odd errors. This is the closest I've gotten to getting CarouselView to work at all. The other packages wouldn't even compile over some strange compatibility issue. That includes the pre-release's as well (with all three different packages I've tried!).
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Flora.Model;
using System.Diagnostics;
using System.Collections.ObjectModel;
namespace Flora
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PlantProfilePage : ContentPage
{
FloraData floraData = new FloraData();
public string familyName { get; }
public string genusName { get; }
public string scientificName { get; }
public string taxonid;
public string indianaFlora { get; set; }
List<string> uriList { get; set; }
ObservableCollection<FloraData.StringData> uris { get; set; }
public PlantProfilePage(string familyName, string genusName, string scientificName, string taxonid)
{
InitializeComponent();
this.familyName = familyName;
this.genusName = genusName;
this.scientificName = scientificName;
this.taxonid = taxonid;
}
protected async override void OnAppearing()
{
base.OnAppearing();
uriList = new List<string>( await floraData.WebScraper(taxonid));
FamilyName.BindingContext = this;
GenusName.BindingContext = this;
ScientificName.BindingContext = this;
indianaFlora = uriList.First();
uriList.Remove(indianaFlora);
Indiana_Flora_description.BindingContext = this;
carousel.BindingContext = floraData;
//PlantPicture.Source = uriList.First();
int m = 0;
uris = new ObservableCollection<FloraData.StringData>();
foreach(var item in uriList)
{
if (m < 5)
{
uris.Add(new FloraData.StringData { uri = item });
m++;
}
}
Debug.WriteLine("Size of uris is " + uris.Count);
carousel.ItemsSource = uris;
}//OnAppearing end
}
}
```
<?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="Flora.PlantProfilePage"
xmlns:control="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms">
<ContentPage.Content>
<ScrollView>
<StackLayout VerticalOptions="Start">
<control:CarouselView x:Name="carousel">
<control:CarouselView.ItemTemplate>
<DataTemplate>
<ffimageloading:CachedImage
x:Name="PlantPicture"
Source="{Binding uri}"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="150"
HeightRequest="150"
DownsampleToViewSize="true">
</ffimageloading:CachedImage>
</DataTemplate>
</control:CarouselView.ItemTemplate>
</control:CarouselView>
<Label x:Name="FamilyName"
Text="{Binding familyName, StringFormat='Family: {0:F0}'}"
HorizontalTextAlignment="Center"
FontAttributes="Bold, Italic"/>
<Label x:Name="GenusName"
Text="{Binding genusName, StringFormat='Genus: {0:F0}'}"
HorizontalTextAlignment="Center"
FontAttributes="Bold, Italic"/>
<Label x:Name="ScientificName"
Text="{Binding scientificName, StringFormat='Scientific Name: {0:F0}'}"
HorizontalTextAlignment="Center"
FontAttributes="Bold, Italic"/>
<Label x:Name="Indiana_Flora_description"
Text="{Binding indianaFlora, StringFormat='Description: {0:F0}'}"
HorizontalOptions="Center"
FontAttributes="Bold"/>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Linq;
using System.Net.Http;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Diagnostics;
using HtmlAgilityPack;
namespace Flora.Model
{
public class FloraData
{
public class StringData
{
public string uri { get; set; }
}
HttpClient client = new HttpClient();
string[] data;
public async Task<string[]> GetData()
{
string uri = "https://search.idigbio.org/v2/search/records?fields=[%22scientificname%22,%22genus%22,%22family%22,%22taxonid%22]&rq={\"county\":\"floyd\",\"stateprovince\":\"Indiana\",\"kingdom\":\"plantae\"}&no_attribution=true&limit=15";
Debug.WriteLine("uri string is: " + uri);
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
Debug.WriteLine("status 200***IsASuccess!");
string content = await response.Content.ReadAsStringAsync();
PlantObject.RootObject dynObj = JsonConvert.DeserializeObject<PlantObject.RootObject>(content);
Debug.WriteLine("deserialization completed...");
data = new string[(dynObj.items.Count * 4)];
Debug.WriteLine("itemCount is " + dynObj.items.Count);
int i = 0;
foreach (var data1 in dynObj.items)
{
Debug.WriteLine(i + "foreach loop iteration");
Debug.WriteLine("family is: " + data1.indexTerms.family);
data[i] = data1.indexTerms.family;
Debug.WriteLine("data[i] newest addition is " + data[i]);
Debug.WriteLine("genus is: " + data1.indexTerms.genus);
data[i + 1] = data1.indexTerms.family + " " + data1.indexTerms.genus;
Debug.WriteLine("data[i+1] newest addition is " + data[i + 1]);
Debug.WriteLine("scientific name is: " + data1.indexTerms.scientificname);
data[i + 2] = data1.indexTerms.scientificname;
Debug.WriteLine("data[i+2] newest addition is " + data[i + 2]);
Debug.WriteLine("taxonid is " + data1.indexTerms.taxonid);
data[i + 3] = data1.indexTerms.taxonid.ToString() + " " + data1.indexTerms.scientificname;
Debug.WriteLine("data[i+3] newest addition is " + data[i + 3]);
i = i + 4;
}
}
}
catch (Exception e)
{
Console.WriteLine("Error retrieving Json data: " + e);
}
return data;
}//GetData end"
List<string> imageURIs = new List<string>();
public async Task<List<string>> WebScraper(string taxonid)
{
//string uri = "http://midwestherbaria.org/portal/taxa/index.php?taxauthid=1&taxon="+taxonid+"&clid=";
int i = 0;
var html = await client.GetStringAsync(#"http://midwestherbaria.org/portal/taxa/index.php?taxauthid=1&taxon=" + taxonid + "&clid=");
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var uriNodes = htmlDoc.DocumentNode.Descendants("div").
Where(x => x.GetAttributeValue("class", "").Equals("tptnimg"));
var descriptionNodes = htmlDoc.DocumentNode.Descendants("div").
Where(x => x.GetAttributeValue("style", "").Equals("clear:both;"));
foreach (var node in descriptionNodes)
{
if (i < 1)
{
var descr = HtmlEntity.DeEntitize(node.InnerText);
imageURIs.Add(descr);
Debug.WriteLine("newest description is " + imageURIs.Last());
break;
}
}
foreach (var node in uriNodes)
{
var uri = HtmlEntity.DeEntitize(node.Descendants("img").FirstOrDefault()?.ChildAttributes("src")
.FirstOrDefault()?.Value);
imageURIs.Add(uri);
Debug.WriteLine("imageURIs list newest item is " + imageURIs.Last());
}
return imageURIs;
}
/*
public async Task<List<string>> GetImage(string scientificName)
{
string uri = "https://search.idigbio.org/v2/search/media?fields=[%22accessuri%22]&rq={\"scientificname\":\"" + scientificName + "\"}&no_attribution=true&limit=1";
Debug.WriteLine("IMAGE: uri string is: " + uri);
HttpClient client = new HttpClient();
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
Debug.WriteLine("IMAGE: status 200***IsASuccess!");
string content = await response.Content.ReadAsStringAsync();
PlantQuery.RootObject dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject<PlantQuery.RootObject>(content);
Debug.WriteLine("IMAGE: deserialization completed...");
//imageURIs = new string[dynObj.itemCount];
Debug.WriteLine("IMAGE: itemCount is " + dynObj.itemCount);
//int i = 0;
foreach (var data1 in dynObj.items)
{
Debug.WriteLine("IMAGE: foreach loop iteration");
Debug.WriteLine("accessURI is: " + data1.indexTerms.accessuri);
imageURIs.Add(data1.indexTerms.accessuri);
Debug.WriteLine("data[i] newest addition is " + imageURIs.Last());
}
}
}
catch (Exception e)
{
Console.WriteLine("Error retrieving Json data: " + e);
}
return imageURIs;
}//GetImage end"
*/
}//FloraData end
}//namespace end
```
I just want the Carousel View to work with around 5 uri images using FFImageLoading for cached images.
EDIT:
here's an example of five uri's that would be in one of the example uris ObservableCollection list:
https://static.inaturalist.org/photos/504134/medium.jpg?1379628103
https://static.inaturalist.org/photos/8784478/small.jpg?1499006293
https://api.idigbio.org/v2/media/23cbb9eb2750e80848ac95b5d2919323?size=thumbnail
https://api.idigbio.org/v2/media/c085496285be91ace0768eb517cc704b?size=thumbnail
http://swbiodiversity.org/imglib/arizona/IND/IND-0049/IND-0049216_1491615930_tn.jpg
Java.Lang.IllegalArgumentException: itemView may not be null
Maybe Source="{Binding uri}" and carousel.BindingContext = floraData; can not get the data.From code BindingContext of using seems like have some problem,you should check that.Suggest that removing labels control from Xaml first ,and check whether CarouselView can work well.
You also can refer to this article about CarouselView.If FloraData class like like this:
public class FloraData
{
public class StringData
{
public string uri { get; set; }
}
public List<StringData> uris { get; set; }
public FloraData()
{
uris = new List<StringData>() { new StringData() { uri = "https://static.inaturalist.org/photos/504134/medium.jpg?1379628103" },
new StringData() { uri = "https://static.inaturalist.org/photos/8784478/small.jpg?1499006293" },
new StringData() { uri = "https://api.idigbio.org/v2/media/23cbb9eb2750e80848ac95b5d2919323?size=thumbnail" },
new StringData() { uri = "https://api.idigbio.org/v2/media/c085496285be91ace0768eb517cc704b?size=thumbnail" },
new StringData() { uri = "http://swbiodiversity.org/imglib/arizona/IND/IND-0049/IND-0049216_1491615930_tn.jpg" }};
}
}
And in ContentPage :
FloraData floraData = new FloraData();
carousel.BindingContext = floraData;
Xaml code as follow:
<StackLayout>
<CarouselView x:Name="carousel" ItemsSource="{Binding uris}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image
x:Name="PlantPicture"
Source="{Binding uri}"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="150"
HeightRequest="150">
</Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
This is easy way to check whether CarouselView work well.
CarouselView : The type initializer for 'Xamarin.Forms.ItemsView' threw an exception
If happen this error, you can refer this and do as follow:
To get started with Xamarin.Forms 4.0 enable all the new features in your MainActivity.cs and AppDelegate.cs via the feature flags api:
global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental", "CollectionView_Experimental");
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
I am using the advanced DataGridView (ADGV) found here to add filtering capabilities to my application.
The code for filtering or sorting is mentioned as:
private void advancedDataGridView1_SortStringChanged(object sender, EventArgs e)
{
this.stockHistoryBindingSource.Sort = advancedDataGridView1.SortString;
}
private void advancedDataGridView1_FilterStringChanged(object sender, EventArgs e)
{
this.stockHistoryBindingSource.Filter = advancedDataGridView1.FilterString;
}
But I can't use this because in my project I am reading an XML file and binding it to my ADGV with this code:
void QueryFoos()
{
IEnumerable<FooViewData> query =
from foo in XmlFiles.FOO.Root.Descendants("foo")
select new FooViewData
{
ID = Convert.ToInt32(foo.Attribute("id").Value),
Num = Convert.ToInt32(foo.Attribute("num").Value),
...
};
advancedDataGridView1.DataSource = query.OrderBy(n => n.ID).ThenBy(r => r.Num).ToList();
}
I tried a code like this but I am not surprised that it is throwing exception in my face:
BindingSource x = (BindingSource)this.advancedDataGridView1.DataSource;
x.Filter = advancedDataGridView1.FilterString;
this.advancedDataGridView1.DataSource = x;
Is there some work around to use the filtering and sorting of the ADGV ?
As it turns out I had this same problem today and was looking for solutions. Basically the problem is that ADGV was written to be used with a DataTable and not a list of objects.
This solution works for me however your mileage may vary.
What I ended up doing was using dynamic linq to perform the filter on the list of objects myself. The hack part was me converting the filter string that ADGV produces and converting it to a string that dynamic linq expects.
We start with some data. I have a class named DataPointGridViewModel that looks like this:
public class DataPointGridViewModel
{
public int DataPointId { get; set; }
public string Description { get; set; }
public bool InAlarm { get; set; }
public DateTime LastUpdate { get; set; }
public double ScalingMultiplier { get; set; }
public decimal Price { get; set; }
}
The data could be anything. This is the data that you will be filtering on in the grid. Obviously you will have your own data class. You need to replace this DataPointGridViewModel clas with your own model/data object.
Now, here is the code example code you need to add. I have also got a sample project on github here: I have a working version of this code on github: here
Here is the code you need to add:
List<DataPointGridViewModel> m_dataGridBindingList = null;
List<DataPointGridViewModel> m_filteredList = null;
private void dataGridView2_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
{
try
{
if ( string.IsNullOrEmpty(dataGridView2.FilterString) == true )
{
m_filteredList = m_dataGridBindingList;
dataGridView2.DataSource = m_dataGridBindingList;
}
else
{
var listfilter = FilterStringconverter(dataGridView2.FilterString);
m_filteredList = m_filteredList.Where(listfilter).ToList();
dataGridView2.DataSource = m_filteredList;
}
}
catch (Exception ex)
{
Log.Error(ex, MethodBase.GetCurrentMethod().Name);
}
}
And this is the function to convert the ADGV filter string to the Dynamic Linq filter string:
private string FilterStringconverter(string filter)
{
string newColFilter = "";
// get rid of all the parenthesis
filter = filter.Replace("(", "").Replace(")", "");
// now split the string on the 'and' (each grid column)
var colFilterList = filter.Split(new string[] { "AND" }, StringSplitOptions.None);
string andOperator = "";
foreach (var colFilter in colFilterList)
{
newColFilter += andOperator;
// split string on the 'in'
var temp1 = colFilter.Trim().Split(new string[] { "IN" }, StringSplitOptions.None);
// get string between square brackets
var colName = temp1[0].Split('[', ']')[1].Trim();
// prepare beginning of linq statement
newColFilter += string.Format("({0} != null && (", colName);
string orOperator = "";
var filterValsList = temp1[1].Split(',');
foreach (var filterVal in filterValsList)
{
// remove any single quotes before testing if filter is a num or not
var cleanFilterVal = filterVal.Replace("'", "").Trim();
double tempNum = 0;
if (Double.TryParse(cleanFilterVal, out tempNum))
newColFilter += string.Format("{0} {1} = {2}", orOperator, colName, cleanFilterVal.Trim());
else
newColFilter += string.Format("{0} {1}.Contains('{2}')", orOperator, colName, cleanFilterVal.Trim());
orOperator = " OR ";
}
newColFilter += "))";
andOperator = " AND ";
}
// replace all single quotes with double quotes
return newColFilter.Replace("'", "\"");
}
...and finally the sort function looks like this:
private void dataGridView2_SortStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.SortEventArgs e)
{
try
{
if (string.IsNullOrEmpty(dataGridView2.SortString) == true)
return;
var sortStr = dataGridView2.SortString.Replace("[", "").Replace("]", "");
if (string.IsNullOrEmpty(dataGridView2.FilterString) == true)
{
// the grid is not filtered!
m_dataGridBindingList = m_dataGridBindingList.OrderBy(sortStr).ToList();
dataGridView2.DataSource = m_dataGridBindingList;
}
else
{
// the grid is filtered!
m_filteredList = m_filteredList.OrderBy(sortStr).ToList();
dataGridView2.DataSource = m_filteredList;
}
}
catch (Exception ex)
{
Log.Error(ex, MethodBase.GetCurrentMethod().Name);
}
}
Finally, you will need the Dynamic Linq library from here
You can use Nuget to bring it into your project:
Install-Package System.Linq.Dynamic
DataTable OrignalADGVdt = null;
private void advancedDataGridView1_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
{
Zuby.ADGV.AdvancedDataGridView fdgv = advancedDataGridView1;
DataTable dt = null;
if (OrignalADGVdt == null)
{
OrignalADGVdt = (DataTable)fdgv.DataSource;
}
if (fdgv.FilterString.Length > 0)
{
dt = (DataTable)fdgv.DataSource;
}
else//Clear Filter
{
dt = OrignalADGVdt;
}
fdgv.DataSource = dt.Select(fdgv.FilterString).CopyToDataTable();
}
Here follow my code sample for filter advanced datagrid
string myFilter = "(Convert([myCol],System.String) IN ('myfilter'))"
dg.LoadFilterAndSort(myFilter, "");
and to clear filter
dg.CleanFilter();
OK this is what I have. I have my main form frmMain.cs and I have a class.cs. I was doing an RSSFeed for my email and I get the error:
inaccessible due to its protective level.
On my class.cs I have the following code:
public class RSSFeed
{
public void CheckForEmails()
{
string GmailAtomUrl = "https://mail.google.com/mail/feed/atom";
XmlUrlResolver xmlResolver = new XmlUrlResolver();
xmlResolver.Credentials = new NetworkCredential(Settings.Default.GmailUser, Settings.Default.GmailPassword);
XmlTextReader xmlReader = new XmlTextReader(GmailAtomUrl);
xmlReader.XmlResolver = xmlResolver;
try
{
XNamespace ns = XNamespace.Get("http://purl.org/atom/ns#");
XDocument xmlFeed = XDocument.Load(xmlReader);
var emailItems = from item in xmlFeed.Descendants(ns + "entry")
select new
{
Author = item.Element(ns + "author").Element(ns + "name").Value,
Title = item.Element(ns + "title").Value,
Link = item.Element(ns + "link").Attribute("href").Value,
Summary = item.Element(ns + "summary").Value
};
frmMain.MsgList.Clear();
frmMain.MsgLink.Clear();
foreach (var item in emailItems)
{
if (item.Title == String.Empty)
{
frmMain.MsgList.Add("Message from " + item.Author + ", There is no subject and the summary reads, " + item.Summary);
frmMain.MsgLink.Add(item.Link);
}
else
{
frmMain.MsgList.Add("Message from " + item.Author + ", The subject is " + item.Title + " and the summary reads, " + item.Summary);
frmMain.MsgLink.Add(item.Link);
}
}
if (emailItems.Count() > 0)
{
if (emailItems.Count() == 1)
{
frmMain.lblEmail.Text = ("You have one new email, would you like me to read it to you");
}
else
{
frmMain.lblEmail.Text("You have " + emailItems.Count() + "new emails");
}
}
else if (frmMain.QEvent == "CheckForNewEmails" && emailItems.Count() == 0)
{
frmMain.lblEmail.Text("You have no new emails"); frmMain.QEvent = String.Empty;
}
}
catch
{
frmMain.lblEmail.Text("You have submitted invalid log in information");
}
}
}
And then I have on my main form a timer tick event:
public void tmrEmail_Tick(object sender, EventArgs e)
{
lblEmail.Text = ("New Emails " + RSSFeed.CheckForEmails);
}
What I am not understanding is when I have the label in my RSSFeed or on my main form timer tick. I get the error. I have changed everything to public and it still is throwing the error.
Am I missing something or do I not have everything I should have?
Also I am going to have another form that is just dedicated to email. Would it be better to do away with the RSSFeed.cs and just code the winform? The only thing this is doing is creating a label when I have new emails.
Any thoughts?
You are missing the static keyword from your class and method. Should be public static class RSSFeed and public static void CheckForEmails()
You need to pass an instance of the frmMain to the method too. E.g.:
public static void CheckForEmails(frmMain frmMainInstance)
Putting it all together:
public static class RSSFeed
{
public static void CheckForEmails(frmMain frmMainInstance)
{
string GmailAtomUrl = "https://mail.google.com/mail/feed/atom";
XmlUrlResolver xmlResolver = new XmlUrlResolver();
// ... rest of your code ...
}
}
And the call to it would be something like:
public void tmrEmail_Tick(object sender, EventArgs e)
{
// The following line will produce a compile error because
// CheckForEmails doesn't return a value
// lblEmail.Text = ("New Emails " + RSSFeed.CheckForEmails(this);
// Try this instead:
RSSFeed.CheckForEmails(this);
}
Note that I am assuming tmrEmail_Tick is a method in frmMain, hence I am passing this as the argument to CheckForEmails.
Instead of making RSSFeed and CheckForEmails static you could instantiate an instance of RSSFeed:
public void tmrEmail_Tick(object sender, EventArgs e)
{
RSSFeed feed = new RSSFeed();
feed.CheckForEmails(this);
}
Note that you still need to pass frmMain instance as an argument to CheckForEmails.
Hi everybody i have a little problem and i hope that somebody could help me
I have a json url that gives me the data like this :
[
{
"nom": "fofo",
"appGuid": "79fa058b-395a-438d-b66f-d751faea82e0"
},
{
"nom": "fifi",
"appGuid": "8b6bfcdb-d286-46e2-889e-0168a782323f"
},
{
"nom": "toto",
"appGuid": "65DE39E7-0130-4836-BBD3-7051574018B6"
},
{
"nom": "titi",
"appGuid": "66DE39E7-0130-4836-BBD3-7051574018B6"
}
]
My class :
public class ListApplication
{
public string nom { get; set; }
public string appGuid { get; set; }
}
I have a listpicker :
I want to bind just the element “nom” in the listpicker, I’ve tried this methods but nothing works:
The first method:
WebClient visio = new WebClient();
visio.DownloadStringCompleted += new DownloadStringCompletedEventHandler(vision_DownloadStringCompleted);
visio.DownloadStringAsync(new Uri("https://......... "));
void vision_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
JArray jArray = JArray.Parse(e.Result);
List<ListApplication> apps = new List<ListApplication>();
for (int i = 0; i < jArray.Count; i++)
{
JObject app = (JObject)jArray[i];
apps.Add(new ListApplication { nom = (string)app["nom"], appGuid = (string)app["appGuid"] });
this.Application.ItemsSource = apps;
//
}
The second method:
public Appli()
{
InitializeComponent();
this.Type_info.ItemsSource = Action;
this.Periode.ItemsSource = Per;
var w = new WebClient();
Observable.FromEvent<DownloadStringCompletedEventArgs>(w, "DownloadStringCompleted").Subscribe(r =>
{
var deserialized =
JsonConvert.DeserializeObject<List<ListApplication>>(r.EventArgs.Result);
Application.ItemsSource = deserialized;
});
w.DownloadStringAsync(
new Uri("https://........"));
}
And then i added Itemsource= {Binding nom} in the listpicker in XAML
Any help I’ll be so appreciative ,and sorry for my English
I believe you are asking that the binding is not taking effect. That is, you cannot see the data in your list.
If that is the case, are you setting the DataContext of the list picker to the List? Also, it seems that you would expect the content of the list picker to change when you receive more JSON data. So, if that is the case i would advise you to use an ObservableCollection instead of a List.
It's ok i found the answer ,i've used this with the second method
<toolkit:ListPicker x:Name="listPicker" Header="Application" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding nom}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>