Binding Problems
Eduardo Gomez Romero
865
Reputation points
So my project is devided into parts
Service
public class WeatherService(HttpClient client) : IWeatherService {
public async Task<Root> GetWeatherDataByCoords(double lat, double lon) {
var responseMessage = await client.GetAsync(
$"{Constant.WEATHER_URL_BASE}/forecast?lat={lat}&lon={lon}&units=metric&appid={Constant.WEATHER_APIkEY}");
if (responseMessage.IsSuccessStatusCode) {
var res = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<Root>(res);
}
return new Root();
}
Model
public class City {
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("coord")]
public Coord Coord { get; set; }
[JsonPropertyName("country")]
public string Country { get; set; }
[JsonPropertyName("population")]
public int Population { get; set; }
[JsonPropertyName("timezone")]
public int Timezone { get; set; }
[JsonPropertyName("sunrise")]
public int Sunrise { get; set; }
[JsonPropertyName("sunset")]
public int Sunset { get; set; }
}
public class Clouds {
[JsonPropertyName("all")]
public int All { get; set; }
}
public class Coord {
[JsonPropertyName("lat")]
public double Lat { get; set; }
[JsonPropertyName("lon")]
public double Lon { get; set; }
}
public class List {
[JsonPropertyName("dt")]
public int Dt { get; set; }
public string dateTime => UtcTimeStamp.ConvertToUtc(Dt);
[JsonPropertyName("main")]
public Main Main { get; set; }
[JsonPropertyName("weather")]
public List<Weather> Weather { get; set; }
[JsonPropertyName("clouds")]
public Clouds Clouds { get; set; }
[JsonPropertyName("wind")]
public Wind Wind { get; set; }
[JsonPropertyName("visibility")]
public int Visibility { get; set; }
[JsonPropertyName("pop")]
public double Pop { get; set; }
[JsonPropertyName("rain")]
public Rain Rain { get; set; }
[JsonPropertyName("sys")]
public Sys Sys { get; set; }
[JsonPropertyName("dt_txt")]
public string DtTxt { get; set; }
}
public class Main {
[JsonPropertyName("temp")]
public double Temp { get; set; }
public double Temperature => Math.Round(Temp);
[JsonPropertyName("feels_like")]
public double FeelsLike { get; set; }
[JsonPropertyName("temp_min")]
public double TempMin { get; set; }
[JsonPropertyName("temp_max")]
public double TempMax { get; set; }
[JsonPropertyName("pressure")]
public int Pressure { get; set; }
[JsonPropertyName("sea_level")]
public int SeaLevel { get; set; }
[JsonPropertyName("grnd_level")]
public int GrndLevel { get; set; }
[JsonPropertyName("humidity")]
public int Humidity { get; set; }
[JsonPropertyName("temp_kf")]
public double TempKf { get; set; }
}
public class Rain {
[JsonPropertyName("3h")]
public double _3h { get; set; }
}
public class Root {
[JsonPropertyName("cod")]
public string Cod { get; set; }
[JsonPropertyName("message")]
public int Message { get; set; }
[JsonPropertyName("cnt")]
public int Cnt { get; set; }
[JsonPropertyName("list")]
public List<List> List { get; set; }
[JsonPropertyName("city")]
public City City { get; set; }
}
public class Sys {
[JsonPropertyName("pod")]
public string Pod { get; set; }
}
public class Weather {
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("main")]
public string Main { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("icon")]
public string Icon { get; set; }
public string IconUrl => $"https://openweathermap.org/img/wn/{Icon}@2x.png";
public string CustomIcon => $"icon_{Icon}.png";
}
public class Wind {
[JsonPropertyName("speed")]
public double Speed { get; set; }
[JsonPropertyName("deg")]
public int Deg { get; set; }
[JsonPropertyName("gust")]
public double Gust { get; set; }
}
View
<ContentPage.Behaviors>
<mct:EventToCommandBehavior
Command="{Binding AppearingCommand}"
EventName="Appearing" />
</ContentPage.Behaviors>
<Grid
IsVisible="{Binding IsVisible}"
RowDefinitions="Auto,Auto,Auto,Auto"
RowSpacing="20">
<StackLayout
Margin="20,20,20,0"
Orientation="Horizontal">
<Border
Padding="10"
Stroke="LightGray">
<Border.StrokeShape>
<RoundRectangle CornerRadius="35" />
</Border.StrokeShape>
<Label
FontAttributes="Bold"
Text="Your Location" />
</Border>
<ImageButton
HeightRequest="30"
HorizontalOptions="EndAndExpand"
Source="searchweather.png"
WidthRequest="30" />
</StackLayout>
<StackLayout Grid.Row="1">
<Label
FontAttributes="Bold"
FontSize="Title"
HorizontalTextAlignment="Center"
Text="{Binding CityName}"
TextColor="Gray" />
<Label
Margin="10"
FontSize="Medium"
HorizontalTextAlignment="Center"
Text="{Binding WeaterDesc}"
TextColor="SlateGray" />
</StackLayout>
<!-- TODO: Bind to the image -->
<Image
Grid.Row="2"
HeightRequest="300"
Source="{Binding WeatherIcon}"
VerticalOptions="Start"
WidthRequest="300" />
<Grid
Grid.Row="3"
Margin="20"
ColumnDefinitions="0.30*,0.30*,0.30*"
RowDefinitions="Auto,Auto">
<Image
Grid.Row="0"
Grid.Column="0"
HeightRequest="25"
Source="humidity.png" />
<!-- TODO: Bind to the humidity -->
<Label
Grid.Row="1"
Grid.Column="0"
HorizontalTextAlignment="Center"
Text="{Binding WeatherHumidity}" />
<!-- TODO: Bind to the current temp -->
<Label
Grid.RowSpan="2"
Grid.Column="1"
FontAttributes="Bold"
FontSize="40"
HorizontalTextAlignment="Center"
Text="{Binding WeatherTemp}" />
<Image
Grid.Row="0"
Grid.Column="2"
HeightRequest="25"
Source="wind.png" />
<!-- TODO: Bind to the wind -->
<Label
Grid.Row="1"
Grid.Column="2"
HorizontalTextAlignment="Center"
Text="{Binding WeatherWind}" />
</Grid>
<CollectionView
Grid.Row="4"
HeightRequest="100"
ItemsLayout="HorizontalList"
ItemsSource="{Binding WeatherList}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Null}">
<Grid RowDefinitions="Auto,Auto,Auto">
<Image
HeightRequest="50"
HorizontalOptions="Center"
Source="{Binding weather[0].CustomIcon}"
VerticalOptions="Start"
WidthRequest="50" />
<Label
Grid.Row="1"
FontSize="Large"
HorizontalTextAlignment="Center"
Text="{Binding Main.Temperature}" />
<Label
Grid.Row="2"
FontSize="Small"
HorizontalTextAlignment="Center"
Text="{Binding dateTime}" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
and VM
public ObservableCollection<List> WeatherList { get; set; } = [];
[ObservableProperty]
string cityName;
[ObservableProperty]
string weaterDesc;
[ObservableProperty]
string weatherTemp;
[ObservableProperty]
string weatherHumidity;
[ObservableProperty]
string weatherWind;
[ObservableProperty]
string weatherIcon;
[ObservableProperty]
bool isVisible = false;
[RelayCommand]
private async Task Appearing() {
await Task.Delay(TimeSpan.FromSeconds(2));
var data = await weatherService.GetWeatherDataByCoords(40.416775, -3.703790);
foreach (var weather in data.List) {
WeatherList.Add(weather);
}
CityName = data.City.Name;
WeaterDesc = data.List[0].Weather[0].Description;
WeatherTemp = $"{data.List[0].Main.Temperature} °C";
WeatherHumidity = $"{data.List[0].Main.Humidity} %";
WeatherWind = $"{data.List[0].Wind.Speed} Km/h";
WeatherIcon = data.List[0].Weather[0].CustomIcon;
IsVisible = true;
}
}
I had to put a delay because I get wrong data sometimes
For example with the lat and lon, it should be Madrid weather and sometimes I get "Sol" in the city name
Anyway, for some reason, my collectionview doesn't want to show anything, and I don't understand, my list has 40 elemernts
and I am binding the Custom image, the temperature, and I use a Library to convert to utc
and I have data
and datetime converted
Sign in to answer