-1

Whenever the variables within weather change, I want to update the objects in Weatherlist so they contain the new updated information.

        [ObservableProperty]
        private ObservableCollection<WeatherData> weatherList = new ObservableCollection<WeatherData>();

        [ObservableProperty]
        private WeatherModel weather;

        private void GetWeatherList()
        {
            WeatherList.Add(new WeatherData()
            {
                WeatherType = "Temperature",
                WeatherTypeData = $"{weather.Temp}°" 
                //I want to update specifically WeatherTypeData whenever private WeatherModel weather changes.
            });
        {

    public partial class WeatherData : ObservableObject
    {
        [ObservableProperty]
        private String weatherType;
        [ObservableProperty]
        private String weatherTypeData;
    }

    public class WeatherModel
    {
        public float Temp { get; set; }
        //This is the information Weathermodel contains
    }

I was hoping adding the following to weather would help:

        [ObservableProperty, NotifyPropertyChangedFor(nameof(WeatherList))]  //Added NotifyPropertyChangedFor
        private WeatherModel weather;

        private void GetWeatherList()
        {
            WeatherList.Add(new WeatherData()
            {
                WeatherType = "Temperature",
                WeatherTypeData = $"{Weather.Temp}°" //Changed capitalization as well
            });
        {

Is there a way to make this work or should I approach this differently?

Wiemar
  • 11
  • 2
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Apr 03 '23 at 13:47

2 Answers2

0

From what you have given GetWeatherList isn't called anywhere, you should use weather.PropertyChanged to update the list whenever the property change. Here is a small example :

public class WeatherData
{
    public string Type { get; set; }
    public float Temp { get; set; }
}

public partial class WeatherModel : ObservableObject
{
    [ObservableProperty]
    private float _Temp = 0;
}

Your ContentPage, with a CollectionView WeatherCollection :

public partial class NewPage1 : ContentPage
{
    private ObservableCollection<WeatherData> _WeatherList = new ObservableCollection<WeatherData>()
    {
        new WeatherData() { Temp = 20 }
    };
    private WeatherModel _Weather = new WeatherModel();

    public NewPage1()
    {
        InitializeComponent();
        WeatherCollection.ItemsSource = _WeatherList;
        _Weather.PropertyChanged += _Weather_PropertyChanged;
    }

    private void _Weather_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName != nameof(WeatherModel.Temp)) return;

        _WeatherList.Add(new WeatherData()
        {
            Type = "temp",
            Temp = _Weather.Temp
        });
    }

    private async void Button_Clicked(object sender, EventArgs e)
    {
        _Weather.Temp += 30;
    }
}
Poulpynator
  • 716
  • 5
  • 13
0

If you want to call method PropertyChanged which changing the value of property Temp of WeatherModel, you can implement event PropertyChanged for Weather which type is WeatherModel.

Weather.PropertyChanged += Weather_PropertyChanged;

I have achieved this function using MVVM.

You can refer to the following code:

MyViewModel.cs

public partial class MyViewModel : ObservableObject 
    {
        [ObservableProperty]
        private ObservableCollection<WeatherData> weatherList = new ObservableCollection<WeatherData>();

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(GetWeatherListCommand))]
        private WeatherModel weather;

        public ICommand TestCommand { get; set; }

        public MyViewModel()
        {
            WeatherList.Add(new WeatherData{ WeatherType = "type1",WeatherTypeData =" 20"});
            WeatherList.Add(new WeatherData { WeatherType = "Temperature", WeatherTypeData = "21" });
            WeatherList.Add(new WeatherData { WeatherType = "type3", WeatherTypeData = " 22" });

            TestCommand = new Command(resetData);


            Weather = new WeatherModel();
            Weather.Temp = 23f;

            Weather.PropertyChanged += Weather_PropertyChanged;
        }

        private void Weather_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            GetWeatherList();
        }

        private void resetData()
        {
             Weather.Temp = 90;
        }

        [RelayCommand]
        private void  GetWeatherList()
        {
            WeatherList.Add(new WeatherData()
            {
                WeatherType = "Temperature",
                WeatherTypeData = Weather.Temp + "°"
            });
        }
    }

WeatherModel.cs

public partial class WeatherModel: ObservableObject 
{
    [ObservableProperty]
    private float temp;
    //This is the information Weathermodel contains
}

WeatherData.cs

public partial class WeatherData: ObservableObject 
{
    [ObservableProperty]
    private String weatherType;
    [ObservableProperty]
    private String weatherTypeData;
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiPassDataApp"
             x:Class="MauiPassDataApp.MainPage">

    <ContentPage.BindingContext>
        <local:MyViewModel></local:MyViewModel>
    </ContentPage.BindingContext>

    <VerticalStackLayout>
        <Button  Text="reset data" Command="{Binding TestCommand}" />

        <ListView ItemsSource="{Binding WeatherList}" HasUnevenRows="True"  x:Name="listview"  >
            <ListView.ItemTemplate>
                <DataTemplate>

                    <ViewCell>
                        <HorizontalStackLayout HeightRequest="38">
                            <Label Text="{Binding WeatherType}" VerticalOptions="Center" FontSize="Caption" ></Label>
                            <Label Text="{Binding WeatherTypeData}"  VerticalOptions="Center"  Margin="20,0,0,0"></Label>

                        </HorizontalStackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </VerticalStackLayout>

</ContentPage>

Note:

The usage of NotifyPropertyChangedFor is not correct, it is for attribute. For more information, you can check Notifying dependent properties

[ObservableProperty, NotifyPropertyChangedFor(nameof(WeatherList))]  //Added NotifyPropertyChangedFor
private WeatherModel weather;

Besides, you can notify dependent commands by NotifyCanExecuteChangedFor.

For example:

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(GetWeatherListCommand))]
        private WeatherModel weather;

And add RelayCommand to function GetWeatherList:

        [RelayCommand]
        private void  GetWeatherList()
        {
            WeatherList.Add(new WeatherData()
            {
                WeatherType = "Temperature",
                WeatherTypeData = Weather.Temp + "°"
            });
        }

but the NotifyCanExecuteChangedFor attribute still doesn't meet your needs: when the value of property Tempin Weather changes, call function GetWeatherList.

Please try use Weather.PropertyChanged += Weather_PropertyChanged; posted in my answer.

Jessie Zhang -MSFT
  • 9,830
  • 1
  • 7
  • 19