I've been working on X.F and databinding. I'm running into a couple of problems. The example runs and displays properly in the Android genymotion emulator. In the iOS emulator, it does not display as I would expect. Some of the images are missing in the listview. A few questions:
1. Do my bindings look correct?
2. There is a set binding value method. I've tried it, and it does not seem to set a value from the data that is bound but seems to be better for setting static values. I'd like to format some data and just stuff it into one of the elements. Is there a good way to do this besides loop through the data and set what I want?
3. On loading the image, is this done via an async call? I'm not doing anything async, so I am concerned that I am doing something wrong.
4. The screenshots show different results. Is there a suggestion on how to get the images to download?
5. The detail property displays below the text property as expected in Android. In iOS, it displays to the right. Is that correct? Examples that I have seen indicate it should be displayed in below. Is there something I am missing to get this to display below the text property?
Thanks for any suggestions.
public class App
{
static NavigationPage np;
static ListView lv;
public static Page GetMainPage ()
{
lv = new ListView(){ RowHeight = 40 };
var cont = new StackLayout(){
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { lv },
};
var contentPage = new ContentPage () {
Content = cont,
};
GetData();
np = new NavigationPage(contentPage);
np.Title = "Weather";
return np;
}
async static void GetData()
{
try{
var d = await GetData("Knoxville, TN");
np.IsBusy = true;
var cellTemplate = new DataTemplate(typeof(ImageCell));
cellTemplate.SetBinding(ImageCell.ImageSourceProperty, "weather[0].icon");
cellTemplate.SetBinding(ImageCell.TextProperty, "weather[0].description");
//cellTemplate.SetValue(ImageCell.DetailProperty, "weather[0].description");
cellTemplate.SetBinding(ImageCell.DetailProperty, "temp.display");
lv.ItemTemplate = cellTemplate;
lv.ItemsSource = d.list;
}
finally{
np.IsBusy = false;
}
}
async static private Task<WeatherReport> GetData(string location)
{
string contents;
WeatherReport res = new WeatherReport();
try
{
string Url = String.Format("http://api.openweathermap.org/data/2.5/forecast/daily?q={0}&mode=json&units=imperial&cnt=14",
location.Trim());
HttpClient hc = new HttpClient();
//var str = //await hc.GetStreamAsync(Url);
contents = await hc.GetStringAsync(Url); // await (new StreamReader(str)).ReadToEndAsync();
res = JsonConvert.DeserializeObject<WeatherReport>(contents);
foreach (var item in res.list)
{
item.weather[0].icon = String.Format("http://openweathermap.org/img/w/{0}.png", item.weather[0].icon);
item.temp.display = String.Format("Max: {0} Min: {1}", item.temp.max, item.temp.min);
System.Diagnostics.Debug.WriteLine(item.weather[0].icon);
}
}
catch (System.Exception sysExc)
{
// Do something to log this error.
throw;
}
return res;
}
}
public class WeatherReport
{
public WeatherReport()
{
list = new List<WeatherDay>();
}
[JsonProperty(PropertyName = "cod")]
public string cod { get; set; }
[JsonProperty(PropertyName = "message")]
public string message { get; set; }
[JsonProperty(PropertyName = "city")]
public WeatherCity city { get; set; }
[JsonProperty(PropertyName = "cnt")]
public int cnt { get; set; }
[JsonProperty(PropertyName = "list")]
public List<WeatherDay> list { get; set; }
}
public class WeatherCity
{
public WeatherCity()
{
}
[JsonProperty(PropertyName = "id")]
public string id { get; set; }
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "coord")]
public coord location { get; set; }
[JsonProperty(PropertyName = "country")]
public string country { get; set; }
[JsonProperty(PropertyName = "population")]
public int population { get; set; }
}
public class coord
{
[JsonProperty(PropertyName = "lat")]
public float lat { get; set; }
[JsonProperty(PropertyName = "lon")]
public float lon { get; set; }
}
public class WeatherDay
{
public WeatherDay()
{
weather = new List<weatherinfo>();
}
[JsonProperty(PropertyName = "dt")]
public int dt { get; set; }
[JsonProperty(PropertyName = "temp")]
public temps temp { get; set; }
[JsonProperty(PropertyName = "pressure")]
public float pressure { get; set; }
[JsonProperty(PropertyName = "humidity")]
public int humidity { get; set; }
[JsonProperty(PropertyName = "weather")]
public List<weatherinfo> weather { get; set; }
}
public class temps
{
[JsonProperty(PropertyName = "day")]
public float day { get; set; }
[JsonProperty(PropertyName = "night")]
public float night { get; set; }
[JsonProperty(PropertyName = "min")]
public float min { get; set; }
[JsonProperty(PropertyName = "max")]
public float max { get; set; }
[JsonProperty(PropertyName = "eve")]
public float eve { get; set; }
[JsonProperty(PropertyName = "morn")]
public float morn { get; set; }
public string display { get; set; }
}
public partial class weatherinfo
{
[JsonProperty(PropertyName = "id")]
public int id { get; set; }
[JsonProperty(PropertyName = "main")]
public string main { get; set; }
[JsonProperty(PropertyName = "description")]
public string description { get; set; }
[JsonProperty(PropertyName = "icon")]
public string icon { get; set; }
public byte[] Image { get; set; }
}