Bind a List property of an object to a ListView

2019-09-20 15:27发布

问题:

I try to work with the openweathermap api (5 days forecast). I've generated the json to C# code which looks like this:

[DataContract]
public class Main
{
    [DataMember]
    public double temp { get; set; }
    [DataMember]
    public double temp_min { get; set; }
    [DataMember]
    public double temp_max { get; set; }
    [DataMember]
    public double pressure { get; set; }
    [DataMember]
    public double sea_level { get; set; }
    [DataMember]
    public double grnd_level { get; set; }
    [DataMember]
    public int humidity { get; set; }
    [DataMember]
    public double temp_kf { get; set; }
}

[DataContract]
public class Weather
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public string main { get; set; }
    [DataMember]
    public string description { get; set; }
    [DataMember]
    public string icon { get; set; }
}

[DataContract]
public class Clouds
{
    [DataMember]
    public int all { get; set; }
}

[DataContract]
public class Wind
{
    [DataMember]
    public double speed { get; set; }
    [DataMember]
    public double deg { get; set; }
}

[DataContract]
public class Sys2
{
    [DataMember]
    public string pod { get; set; }
}

/*public class Rain
{
    public double __invalid_name__3h { get; set; }
}*/

[DataContract]
public class List
{
    [DataMember]
    public int dt { get; set; }
    [DataMember]
    public Main main { get; set; }
    [DataMember]
    public List<Weather> weather { get; set; }
    [DataMember]
    public Clouds clouds { get; set; }
    [DataMember]
    public Wind wind { get; set; }
    [DataMember]
    public Sys2 sys { get; set; }
    [DataMember]
    public string dt_txt { get; set; }
    //public Rain rain { get; set; }
}

[DataContract]
public class RootObject
{
    [DataMember]
    public City city { get; set; }
    [DataMember]
    public string cod { get; set; }
    [DataMember]
    public double message { get; set; }
    [DataMember]
    public int cnt { get; set; }
    [DataMember]
    public List<List> list { get; set; }
}

Then after I have my RootObject which holds all the data forecast I try to bind a list of the first ten temperatures to a ListView.

EDIT:

public sealed partial class MainPage : Page
{

    private List<double> TemperatureObjects;
    private ObservableCollection<RootObject> WeatherObjects;

My XAML looks like that:

  <ListView Grid.Row="2" ItemsSource="{x:Bind WeatherObjects}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:RootObject">
                <StackPanel Orientation="Vertical">
                    <TextBlock>
                        <Run Text="{x:Bind Temp}"/>
                        <Run Text="&#xE00BA;"/>
                    </TextBlock>

                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Can you show me some help for this issue? thanks

回答1:

As for now I see at least three things you need to correct:

  • implement INotifyPropertyChanged in your MainPage, for example like this:

    public partial class MainPage: Page, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    
  • your objects which you bind to, should be public properties:

    private ObservableCollection<RootObject> weatherObjects;
    
    public ObservableCollection<RootObject> WeatherObjects
    {
        get { return weatherObjects; }
        set { weatherObjects= value; RaiseProperty(nameof(WeatherObjects)); }
    }
    
  • depending on your code, you may also need to change binding's mode from default's OneTime:

    <ListView Grid.Row="2" ItemsSource="{x:Bind WeatherObjects, Mode="OneWay"}">
    

You don't need to set the DataContext as you are using x:Bind.