Binding Problems

Eduardo Gomez Romero 225 Reputation points
2024-06-26T20:32:33.0233333+00:00

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

User's image

and I am binding the Custom image, the temperature, and I use a Library to convert to utc

and I have data

User's image

and datetime converted

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,174 questions
{count} votes