admin管理员组

文章数量:1026147

The app crash when I am trying to populate the carrouselView a second time. When the app start I get data to display on carrouselView, it work the first time on IOS and Android:

Here is the xalm :

<CarouselView x:Name="newsCarousel"
                          Position="{Binding CurrentCarouselIndex, Mode=TwoWay}"
                          Loop="False"
                          IsVisible="{Binding IsLoading, Converter={StaticResource boolToBoolInvertConverter}}"
                          ItemsSource="{Binding CarouselNewsList}"
                          Grid.Row="0"
                          IndicatorView="indicatorview">
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="models:NewsModel">
                        <Border HeightRequest="150"
                                Padding="0"
                                Margin="0"
                                StrokeShape="RoundRectangle 10"
                                Stroke="Transparent">

                            <Grid>
                                <Image   Source="{Binding NewsImageUrl, Converter={StaticResource imageResizerConverter}}"
                                         Aspect="AspectFill"/>


                                <Grid Background="{StaticResource GradientBlack}">


                                    <StackLayout VerticalOptions="End"
                                                 Spacing="5"
                                                 Padding="20,0,0,20">
                                        <Label Text="{Binding NewsName}"
                                               Grid.Row="1"
                                               TextColor="{StaticResource White}"
                                               FontSize="{StaticResource MiddleSize}"/>
                                        <Label Text="{Binding NewsProvider}"
                                               Grid.Row="2"
                                               TextColor="{StaticResource White}"
                                               FontSize="{StaticResource SmallSize}"/>
                                    </StackLayout>

                                </Grid>

                            </Grid>

                            <Border.GestureRecognizers>
                                <TapGestureRecognizer Tapped="OnNewsItemTapped"/>
                            </Border.GestureRecognizers>
                        </Border>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <IndicatorView  x:Name="indicatorview"
                            IsVisible="{Binding IsLoading, Converter={StaticResource boolToBoolInvertConverter}}"
                            HorizontalOptions="End"
                            IndicatorColor="White"
                            IndicatorsShape="Circle"
                            MaximumVisible="6"
                            IndicatorSize="4"
                            Margin="20"
                            VerticalOptions="EndAndExpand"
                            SelectedIndicatorColor="#0F9D58"/>

Here is the View Model :

public partial class NewsViewModel : ObservableObject
{



    [ObservableProperty]
    private bool isFilterVisible;


    [ObservableProperty]
    private bool isSearchingNews;


    [ObservableProperty]
    private string userNewsLanguageCode;

    [ObservableProperty]
    private string newsTitlePage;


    [ObservableProperty]
    private string categoryToFilter;

    [ObservableProperty]
    private string searchNewsText;

    [ObservableProperty]
    private string searchNewsPlaceholder;





    [ObservableProperty]
    private string imageFiltered;

    [ObservableProperty]
    private int currentCarouselIndex;

    public ObservableCollection<NewsModel> NewsList { get; set; }
    public ObservableCollection<NewsModel> CarouselNewsList { get; set; }

    public ObservableCollection<NewsModel> FilteredNewsList { get; set; }

    private int _currentOffset = 0;
    private const int _limit = 30;
    public IAsyncRelayCommand LoadNewsCommand { get; }
    public IAsyncRelayCommand LoadMoreNewsCommand { get; }

    public ObservableCollection<NewsCountryListModel> MySortedDictionnaryLang { get; set; }
    private ObservableCollection<NewsCountryListModel> _allLanguages;


    public ObservableCollection<NewsCategoryListModel> MySortedDictionnaryNewsCategory { get; set; }
    private ObservableCollection<NewsCategoryListModel> _allnewscategory;



    [ObservableProperty]
    private bool isLoadingCountry;


    [ObservableProperty]
    private bool isLoadingNewsCategory;


    [ObservableProperty]
    private string searchCloseImg;

    [ObservableProperty]
    private string cancelFilterLabel;
    [ObservableProperty]
    private string countriesLabel;

    [ObservableProperty]
    private string channelLabel;



    private readonly UserDatabaseService _userdatabaseService;

    [Obsolete]
    public NewsViewModel(UserDatabaseService userdatabaseService)
    {
        _userdatabaseService = userdatabaseService;
        var languageSettings = App.LanguageSettings;
        searchCloseImg = "searchblackicon";
        NewsTitlePage = languageSettings.NewsTitel;
        ImageFiltered = "filterblack";
        SearchNewsPlaceholder = languageSettings.SearchNews;
        UserNewsLanguageCode = "en-US";

        CancelFilterLabel = languageSettings.CancelFilterLabel;
        CountriesLabel = languageSettings.Countries;
        ChannelLabel = languageSettings.ChannelLabel;



        MySortedDictionnaryLang = new ObservableCollection<NewsCountryListModel>();
        _allLanguages = new ObservableCollection<NewsCountryListModel>();

        MySortedDictionnaryNewsCategory = new ObservableCollection<NewsCategoryListModel>();
        _allnewscategory = new ObservableCollection<NewsCategoryListModel>();


        // CardsList  Load data here 
        CarouselNewsList = new ObservableCollection<NewsModel>(); // Initialize the collection
        NewsList = new ObservableCollection<NewsModel>(); // Initialize the collection
        FilteredNewsList = new ObservableCollection<NewsModel>(); // Initialize the collection



        LoadNewsCommand = new AsyncRelayCommand(LoadNewsAsync);
        LoadMoreNewsCommand = new AsyncRelayCommand(LoadMoreNewsAsync);
        LoadNewsCommand.Execute(null);
        //InitializeAsync();



        LoadCountryListCommand = new AsyncRelayCommand(LoadCountriesListAsync);
        LoadCountryListCommand.Execute(null);


        LoadNewsCategoryListCommand = new AsyncRelayCommand(LoadNewsCategoryListAsync);
        LoadNewsCategoryListCommand.Execute(null);

        MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.GoPage.ToString());



        // Subscribe to the NewsCountrySelectedMessage
        WeakReferenceMessenger.Default.Register<NewsCountrySelectedMessage>(this, async (r, m) =>
        {
            UserNewsLanguageCode = m.Value.Code;
            NumberAddedNews = 0;
            ImageFiltered = "filterblack";
            CategoryToFilter = string.Empty;

            MyMvvMuser.NewsLanguage = UserNewsLanguageCode;
            MyFunctionShared.UpdateUserInAllDatabse(MyMvvMuser);

            LoadNewsCommand.Execute(null);
            LoadNewsCategoryListCommand.Execute(null);


        });


        WeakReferenceMessenger.Default.Register<NewsCategorySelectedMessage>(this, async (r, m) =>
     {

         ImageFiltered = m.Value.CodeLower;
         CategoryToFilter = m.Value.Code;
         NumberAddedNews = 0;
         LoadNewsCommand.Execute(null);

     });

        // Subscribe to the ClearCategoryFilterMessage
        WeakReferenceMessenger.Default.Register<ClearCategoryFilterMessage>(this, (r, m) =>
        {
            CategoryToFilter = string.Empty;//m.Value;
            ImageFiltered = "filterblack";
            NumberAddedNews = 0;
            LoadNewsCommand.Execute(null);
        });


    }

    MyUser MyMvvMuser { get; set; }
    async Task GetLocalDB()
    {

        MyMvvMuser = new MyUser();
        MyMvvMuser = await _userdatabaseService.GetUserAsync();

        if (!string.IsNullOrWhiteSpace(MyMvvMuser.NewsLanguage))
        {
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

        }
        else
        {
            SetNewsLanguage(MyMvvMuser);
        }
    }

    // Set News Language When the app start
    void SetNewsLanguage(MyUser _tmpuser)
    {
        string UserLanguage = _tmpuser.LanguageKey2;
        var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
        var langDictionary = GetAppLanguageSetup.GetAppJsonNewsListOfLanguage(phoneLanguage);
        var sortedLangDictionary = new SortedDictionary<string, string>(langDictionary);
        // Find the first key that contains UserLanguage
        string selectedLanguage = sortedLangDictionary.Keys
            .FirstOrDefault(key => key.Contains(UserLanguage)) ?? "en-US";

        _tmpuser.NewsLanguage = selectedLanguage;
        UserNewsLanguageCode = MyMvvMuser.NewsLanguage;
    }


    public IAsyncRelayCommand LoadCountryListCommand { get; }
    public IAsyncRelayCommand LoadNewsCategoryListCommand { get; }


    public async Task LoadNewsCategoryListAsync()
    {

        IsLoadingNewsCategory = true;

        await Task.Run(async () =>
  {
      var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
      var langDictionaryNewsCategory = GetAppLanguageSetup.GetAppJsonNewsListCategory(phoneLanguage);
      var sortedLangDictionaryCategory = new SortedDictionary<string, string>(langDictionaryNewsCategory);

      // Get the unique categories
      var uniqueCategories = await NewsDataAPIManager.GetNewsUniqueCategory(UserNewsLanguageCode);


      // Filter the categories
      var tempCollectionCategory = sortedLangDictionaryCategory
           .Where(kvp => uniqueCategories.Contains(kvp.Key))
           .Select(kvp => new NewsCategoryListModel { Code = kvp.Key, Name = kvp.Value })
           .OrderBy(x => x.Name)
           .ToList();


      await MainThread.InvokeOnMainThreadAsync(() =>
  {
      MySortedDictionnaryNewsCategory.Clear();
      _allnewscategory.Clear();

      foreach (var item in tempCollectionCategory)
      {
          MySortedDictionnaryNewsCategory.Add(item);
          _allnewscategory.Add(item);
      }
      IsLoadingNewsCategory = false;
  });

  });


    }

    public async Task LoadCountriesListAsync()
    {
        IsLoadingCountry = true;

        await Task.Run(async () =>
        {
            var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
            var langDictionary = GetAppLanguageSetup.GetAppJsonNewsListOfLanguage(phoneLanguage);
            var sortedLangDictionary = new SortedDictionary<string, string>(langDictionary);
            var tempCollection = sortedLangDictionary
                .Select(kvp => new NewsCountryListModel { Code = kvp.Key, Name = kvp.Value })
                .OrderBy(x => x.Name)
                .ToList();
            await MainThread.InvokeOnMainThreadAsync(() =>
            {
                MySortedDictionnaryLang.Clear();
                _allLanguages.Clear();

                foreach (var item in tempCollection)
                {
                    MySortedDictionnaryLang.Add(item);
                    _allLanguages.Add(item);
                }
                IsLoadingCountry = false;
            });

        });



    }





    [ObservableProperty]
    private bool isLoading;


    private bool IsNewsExist;




    int NumberAddedNews = 0;//Allow to add news in Carrousel
    private async Task LoadNewsAsync()
    {
        IsLoading = true;

        try
        {
            await GetLocalDB();
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

            _currentOffset = 0;
            var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);
            IsNewsExist = MyFunctionShared.IsListNotNullOrEmpty(MyNewsData);


            await MainThread.InvokeOnMainThreadAsync(() =>
               {

                   NewsList.Clear();
                   CarouselNewsList.Clear();

                   try
                   {
                       if (IsNewsExist)
                       {

                           foreach (var nw in MyNewsData)
                           {
                               if (NumberAddedNews <= 3)
                               {
                                 //  CarouselNewsList.Add(nw);
                               }
                               else
                               {
                                   NewsList.Add(nw);
                               }

                               NumberAddedNews++;

                           }

                           _currentOffset += _limit;

                       }

                   }

                   catch (Exception ex)
                   {
                       Debug.WriteLine($"Theerror : {ex.Message}");

                   }



               });





        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.WriteLine($"Error loading cards: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
        }
    }

    private bool isAddingCards = false;
    private async Task LoadMoreNewsAsync()
    {
        // add condition to not enter here
        if (isAddingCards == false)
        {
            try
            {
                isAddingCards = true;
                var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);
                await MainThread.InvokeOnMainThreadAsync(() =>
                {
                    foreach (var nw in MyNewsData)
                    {
                        NewsList.Add(nw);
                    }
                });

                _currentOffset += _limit;
            }
            catch (Exception ex)
            {
                // Handle exceptions (e.g., log the error)
                Console.WriteLine($"Error loading more cards: {ex.Message}");
            }
            finally
            {
                isAddingCards = false;
            }
        }
    }


    [ObservableProperty]
    private bool isNewsRefreshing;

    [RelayCommand]
    private async Task MyRefresh()
    {
        IsNewsRefreshing = true;

        try
        {
            CategoryToFilter = string.Empty;//m.Value;
            ImageFiltered = "filterblack";
            NumberAddedNews = 0;
            LoadNewsCommand.Execute(null);
        }
        finally
        {
            IsNewsRefreshing = false;
        }
    }

    [Obsolete]
    private void InitializeAsync()
    {
        AutoSwipeCarousel();
    }

    [Obsolete]
    private void AutoSwipeCarousel()
    {
        Device.StartTimer(TimeSpan.FromSeconds(7), () =>
        {
            if (IsNewsExist == true)
            {
                CurrentCarouselIndex = (CurrentCarouselIndex + 1) % CarouselNewsList.Count;
                return true; // Return true to keep the timer running
            }
            else
            {
                return true; // Return true to keep the timer running

            }

        });
    }



}

Here is the cs code :

public partial class MyNewsPage : ContentPage
{
    private NewsViewModel _viewModel;

    [Obsolete]
    public MyNewsPage()
    {
        InitializeComponent();
        _viewModel = new NewsViewModel(App.UserDatabase);
        BindingContext = _viewModel;
        // Add this line to bind the CarouselView's position
      //  newsCarousel.SetBinding(CarouselView.PositionProperty, new Binding(nameof(NewsViewModel.CurrentCarouselIndex), BindingMode.TwoWay));

    }

    [Obsolete]
    void OnShowBottonSheetFilterCountry(System.Object sender, System.EventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(async () =>
           {

               var page = new NewsListCountryBottomSheet();
               page.HasHandle = false;
               await page.ShowAsync(Window);
           });

                   MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.ChangeCountryNews.ToString());

    }

    [Obsolete]
    void OnShowBottonSheetFilterNews(System.Object sender, System.EventArgs e)
    {

        var viewModel = BindingContext as NewsViewModel;
        MainThread.BeginInvokeOnMainThread(async () =>
{

    var page = new NewsFilterCategoryBottomSheet(viewModel.UserNewsLanguageCode, viewModel.CategoryToFilter);
    page.HasHandle = false;
    await page.ShowAsync(Window);
});

        MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.FilteredNews.ToString());

    }


    UserNewsReadModel usernewsread;
    async void OnNewsItemTapped(System.Object sender, System.EventArgs e)
    {
        var tappedItem = (sender as Border).BindingContext as NewsModel;


        if (tappedItem != null && !string.IsNullOrEmpty(tappedItem.NewsUrl))
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {

                usernewsread = new UserNewsReadModel();
                usernewsread.UserId = Preferences.Default.Get("MyUserId", "");
                usernewsread.Language = tappedItem.Language;
                usernewsread.NewsName = tappedItem.NewsName;
                usernewsread.NewsUrl = tappedItem.NewsUrl;
                usernewsread.NewsProvider = tappedItem.NewsProvider;
                usernewsread.NewsImageUrl = tappedItem.NewsImageUrl;
                usernewsread.NewsDate = tappedItem.NewsDate;
                usernewsread.NewsCategory = tappedItem.NewsCategory;
                usernewsread.LeafProvider = tappedItem.LeafProvider;

                var page = new NewsBottomSheet(usernewsread);
                page.HasHandle = false;
                await page.ShowAsync(Window);
            });

                    MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.SeenNews.ToString());
        }
    }


    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();

        // Subscribe to the visibility changes
        _viewModel.PropertyChanged += ViewModel_PropertyChanged;
    }

    private async void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(NewsViewModel.IsSearchingNews))
        {
            if (_viewModel.IsSearchingNews)
            {
                await NewsMenuLayout.FadeTo(0, 250);
            }
            else
            {
                await NewsMenuLayout.FadeTo(1, 250);
            }
        }

    }

    /*
        private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
        {
            _viewModel.FilterNewsList(e.NewTextValue);
        }*/





}

Here is the function to load the data :

    int NumberAddedNews = 0;//Allow to add news in Carrousel
    private async Task LoadNewsAsync()
    {
        IsLoading = true;

        try
        {
            await GetLocalDB();
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

            _currentOffset = 0;
            var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);

            IsNewsExist = MyFunctionShared.IsListNotNullOrEmpty(MyNewsData);


            await MainThread.InvokeOnMainThreadAsync(() =>
               {
                   
                   NewsList.Clear();
                   CarouselNewsList.Clear();

                   if (IsNewsExist)
                   {

                       foreach (var nw in MyNewsData)
                       {
                           if (NumberAddedNews <= 3)
                           {
                               CarouselNewsList.Add(nw); // got an error here when receiveing the message
                           }
                           else
                           {
                               NewsList.Add(nw);
                           }

                           NumberAddedNews++;

                       }

                       _currentOffset += _limit;

                   }

               });





        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.WriteLine($"Error loading cards: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
        }
    }



To reload the data I receive a message so that the data are reloaded : 

      // Subscribe to the NewsCountrySelectedMessage
        WeakReferenceMessenger.Default.Register<NewsCountrySelectedMessage>(this, async (r, m) =>
        {
            UserNewsLanguageCode = m.Value.Code;
            NumberAddedNews = 0;
            ImageFiltered = "filterblack";
            CategoryToFilter = string.Empty;
            MyMvvMuser.NewsLanguage = UserNewsLanguageCode;
            LoadNewsCommand.Execute(null);


        });

My Problem : The reload work well on IOS but not on Android the app crash at the line " CarouselNewsList.Add(nw);" of the function LoadNewsAsync. I think it is a UI Issue and I do not see any error triggered

The app crash when I am trying to populate the carrouselView a second time. When the app start I get data to display on carrouselView, it work the first time on IOS and Android:

Here is the xalm :

<CarouselView x:Name="newsCarousel"
                          Position="{Binding CurrentCarouselIndex, Mode=TwoWay}"
                          Loop="False"
                          IsVisible="{Binding IsLoading, Converter={StaticResource boolToBoolInvertConverter}}"
                          ItemsSource="{Binding CarouselNewsList}"
                          Grid.Row="0"
                          IndicatorView="indicatorview">
                <CarouselView.ItemTemplate>
                    <DataTemplate x:DataType="models:NewsModel">
                        <Border HeightRequest="150"
                                Padding="0"
                                Margin="0"
                                StrokeShape="RoundRectangle 10"
                                Stroke="Transparent">

                            <Grid>
                                <Image   Source="{Binding NewsImageUrl, Converter={StaticResource imageResizerConverter}}"
                                         Aspect="AspectFill"/>


                                <Grid Background="{StaticResource GradientBlack}">


                                    <StackLayout VerticalOptions="End"
                                                 Spacing="5"
                                                 Padding="20,0,0,20">
                                        <Label Text="{Binding NewsName}"
                                               Grid.Row="1"
                                               TextColor="{StaticResource White}"
                                               FontSize="{StaticResource MiddleSize}"/>
                                        <Label Text="{Binding NewsProvider}"
                                               Grid.Row="2"
                                               TextColor="{StaticResource White}"
                                               FontSize="{StaticResource SmallSize}"/>
                                    </StackLayout>

                                </Grid>

                            </Grid>

                            <Border.GestureRecognizers>
                                <TapGestureRecognizer Tapped="OnNewsItemTapped"/>
                            </Border.GestureRecognizers>
                        </Border>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
            <IndicatorView  x:Name="indicatorview"
                            IsVisible="{Binding IsLoading, Converter={StaticResource boolToBoolInvertConverter}}"
                            HorizontalOptions="End"
                            IndicatorColor="White"
                            IndicatorsShape="Circle"
                            MaximumVisible="6"
                            IndicatorSize="4"
                            Margin="20"
                            VerticalOptions="EndAndExpand"
                            SelectedIndicatorColor="#0F9D58"/>

Here is the View Model :

public partial class NewsViewModel : ObservableObject
{



    [ObservableProperty]
    private bool isFilterVisible;


    [ObservableProperty]
    private bool isSearchingNews;


    [ObservableProperty]
    private string userNewsLanguageCode;

    [ObservableProperty]
    private string newsTitlePage;


    [ObservableProperty]
    private string categoryToFilter;

    [ObservableProperty]
    private string searchNewsText;

    [ObservableProperty]
    private string searchNewsPlaceholder;





    [ObservableProperty]
    private string imageFiltered;

    [ObservableProperty]
    private int currentCarouselIndex;

    public ObservableCollection<NewsModel> NewsList { get; set; }
    public ObservableCollection<NewsModel> CarouselNewsList { get; set; }

    public ObservableCollection<NewsModel> FilteredNewsList { get; set; }

    private int _currentOffset = 0;
    private const int _limit = 30;
    public IAsyncRelayCommand LoadNewsCommand { get; }
    public IAsyncRelayCommand LoadMoreNewsCommand { get; }

    public ObservableCollection<NewsCountryListModel> MySortedDictionnaryLang { get; set; }
    private ObservableCollection<NewsCountryListModel> _allLanguages;


    public ObservableCollection<NewsCategoryListModel> MySortedDictionnaryNewsCategory { get; set; }
    private ObservableCollection<NewsCategoryListModel> _allnewscategory;



    [ObservableProperty]
    private bool isLoadingCountry;


    [ObservableProperty]
    private bool isLoadingNewsCategory;


    [ObservableProperty]
    private string searchCloseImg;

    [ObservableProperty]
    private string cancelFilterLabel;
    [ObservableProperty]
    private string countriesLabel;

    [ObservableProperty]
    private string channelLabel;



    private readonly UserDatabaseService _userdatabaseService;

    [Obsolete]
    public NewsViewModel(UserDatabaseService userdatabaseService)
    {
        _userdatabaseService = userdatabaseService;
        var languageSettings = App.LanguageSettings;
        searchCloseImg = "searchblackicon";
        NewsTitlePage = languageSettings.NewsTitel;
        ImageFiltered = "filterblack";
        SearchNewsPlaceholder = languageSettings.SearchNews;
        UserNewsLanguageCode = "en-US";

        CancelFilterLabel = languageSettings.CancelFilterLabel;
        CountriesLabel = languageSettings.Countries;
        ChannelLabel = languageSettings.ChannelLabel;



        MySortedDictionnaryLang = new ObservableCollection<NewsCountryListModel>();
        _allLanguages = new ObservableCollection<NewsCountryListModel>();

        MySortedDictionnaryNewsCategory = new ObservableCollection<NewsCategoryListModel>();
        _allnewscategory = new ObservableCollection<NewsCategoryListModel>();


        // CardsList  Load data here 
        CarouselNewsList = new ObservableCollection<NewsModel>(); // Initialize the collection
        NewsList = new ObservableCollection<NewsModel>(); // Initialize the collection
        FilteredNewsList = new ObservableCollection<NewsModel>(); // Initialize the collection



        LoadNewsCommand = new AsyncRelayCommand(LoadNewsAsync);
        LoadMoreNewsCommand = new AsyncRelayCommand(LoadMoreNewsAsync);
        LoadNewsCommand.Execute(null);
        //InitializeAsync();



        LoadCountryListCommand = new AsyncRelayCommand(LoadCountriesListAsync);
        LoadCountryListCommand.Execute(null);


        LoadNewsCategoryListCommand = new AsyncRelayCommand(LoadNewsCategoryListAsync);
        LoadNewsCategoryListCommand.Execute(null);

        MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.GoPage.ToString());



        // Subscribe to the NewsCountrySelectedMessage
        WeakReferenceMessenger.Default.Register<NewsCountrySelectedMessage>(this, async (r, m) =>
        {
            UserNewsLanguageCode = m.Value.Code;
            NumberAddedNews = 0;
            ImageFiltered = "filterblack";
            CategoryToFilter = string.Empty;

            MyMvvMuser.NewsLanguage = UserNewsLanguageCode;
            MyFunctionShared.UpdateUserInAllDatabse(MyMvvMuser);

            LoadNewsCommand.Execute(null);
            LoadNewsCategoryListCommand.Execute(null);


        });


        WeakReferenceMessenger.Default.Register<NewsCategorySelectedMessage>(this, async (r, m) =>
     {

         ImageFiltered = m.Value.CodeLower;
         CategoryToFilter = m.Value.Code;
         NumberAddedNews = 0;
         LoadNewsCommand.Execute(null);

     });

        // Subscribe to the ClearCategoryFilterMessage
        WeakReferenceMessenger.Default.Register<ClearCategoryFilterMessage>(this, (r, m) =>
        {
            CategoryToFilter = string.Empty;//m.Value;
            ImageFiltered = "filterblack";
            NumberAddedNews = 0;
            LoadNewsCommand.Execute(null);
        });


    }

    MyUser MyMvvMuser { get; set; }
    async Task GetLocalDB()
    {

        MyMvvMuser = new MyUser();
        MyMvvMuser = await _userdatabaseService.GetUserAsync();

        if (!string.IsNullOrWhiteSpace(MyMvvMuser.NewsLanguage))
        {
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

        }
        else
        {
            SetNewsLanguage(MyMvvMuser);
        }
    }

    // Set News Language When the app start
    void SetNewsLanguage(MyUser _tmpuser)
    {
        string UserLanguage = _tmpuser.LanguageKey2;
        var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
        var langDictionary = GetAppLanguageSetup.GetAppJsonNewsListOfLanguage(phoneLanguage);
        var sortedLangDictionary = new SortedDictionary<string, string>(langDictionary);
        // Find the first key that contains UserLanguage
        string selectedLanguage = sortedLangDictionary.Keys
            .FirstOrDefault(key => key.Contains(UserLanguage)) ?? "en-US";

        _tmpuser.NewsLanguage = selectedLanguage;
        UserNewsLanguageCode = MyMvvMuser.NewsLanguage;
    }


    public IAsyncRelayCommand LoadCountryListCommand { get; }
    public IAsyncRelayCommand LoadNewsCategoryListCommand { get; }


    public async Task LoadNewsCategoryListAsync()
    {

        IsLoadingNewsCategory = true;

        await Task.Run(async () =>
  {
      var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
      var langDictionaryNewsCategory = GetAppLanguageSetup.GetAppJsonNewsListCategory(phoneLanguage);
      var sortedLangDictionaryCategory = new SortedDictionary<string, string>(langDictionaryNewsCategory);

      // Get the unique categories
      var uniqueCategories = await NewsDataAPIManager.GetNewsUniqueCategory(UserNewsLanguageCode);


      // Filter the categories
      var tempCollectionCategory = sortedLangDictionaryCategory
           .Where(kvp => uniqueCategories.Contains(kvp.Key))
           .Select(kvp => new NewsCategoryListModel { Code = kvp.Key, Name = kvp.Value })
           .OrderBy(x => x.Name)
           .ToList();


      await MainThread.InvokeOnMainThreadAsync(() =>
  {
      MySortedDictionnaryNewsCategory.Clear();
      _allnewscategory.Clear();

      foreach (var item in tempCollectionCategory)
      {
          MySortedDictionnaryNewsCategory.Add(item);
          _allnewscategory.Add(item);
      }
      IsLoadingNewsCategory = false;
  });

  });


    }

    public async Task LoadCountriesListAsync()
    {
        IsLoadingCountry = true;

        await Task.Run(async () =>
        {
            var phoneLanguage = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
            var langDictionary = GetAppLanguageSetup.GetAppJsonNewsListOfLanguage(phoneLanguage);
            var sortedLangDictionary = new SortedDictionary<string, string>(langDictionary);
            var tempCollection = sortedLangDictionary
                .Select(kvp => new NewsCountryListModel { Code = kvp.Key, Name = kvp.Value })
                .OrderBy(x => x.Name)
                .ToList();
            await MainThread.InvokeOnMainThreadAsync(() =>
            {
                MySortedDictionnaryLang.Clear();
                _allLanguages.Clear();

                foreach (var item in tempCollection)
                {
                    MySortedDictionnaryLang.Add(item);
                    _allLanguages.Add(item);
                }
                IsLoadingCountry = false;
            });

        });



    }





    [ObservableProperty]
    private bool isLoading;


    private bool IsNewsExist;




    int NumberAddedNews = 0;//Allow to add news in Carrousel
    private async Task LoadNewsAsync()
    {
        IsLoading = true;

        try
        {
            await GetLocalDB();
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

            _currentOffset = 0;
            var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);
            IsNewsExist = MyFunctionShared.IsListNotNullOrEmpty(MyNewsData);


            await MainThread.InvokeOnMainThreadAsync(() =>
               {

                   NewsList.Clear();
                   CarouselNewsList.Clear();

                   try
                   {
                       if (IsNewsExist)
                       {

                           foreach (var nw in MyNewsData)
                           {
                               if (NumberAddedNews <= 3)
                               {
                                 //  CarouselNewsList.Add(nw);
                               }
                               else
                               {
                                   NewsList.Add(nw);
                               }

                               NumberAddedNews++;

                           }

                           _currentOffset += _limit;

                       }

                   }

                   catch (Exception ex)
                   {
                       Debug.WriteLine($"Theerror : {ex.Message}");

                   }



               });





        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.WriteLine($"Error loading cards: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
        }
    }

    private bool isAddingCards = false;
    private async Task LoadMoreNewsAsync()
    {
        // add condition to not enter here
        if (isAddingCards == false)
        {
            try
            {
                isAddingCards = true;
                var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);
                await MainThread.InvokeOnMainThreadAsync(() =>
                {
                    foreach (var nw in MyNewsData)
                    {
                        NewsList.Add(nw);
                    }
                });

                _currentOffset += _limit;
            }
            catch (Exception ex)
            {
                // Handle exceptions (e.g., log the error)
                Console.WriteLine($"Error loading more cards: {ex.Message}");
            }
            finally
            {
                isAddingCards = false;
            }
        }
    }


    [ObservableProperty]
    private bool isNewsRefreshing;

    [RelayCommand]
    private async Task MyRefresh()
    {
        IsNewsRefreshing = true;

        try
        {
            CategoryToFilter = string.Empty;//m.Value;
            ImageFiltered = "filterblack";
            NumberAddedNews = 0;
            LoadNewsCommand.Execute(null);
        }
        finally
        {
            IsNewsRefreshing = false;
        }
    }

    [Obsolete]
    private void InitializeAsync()
    {
        AutoSwipeCarousel();
    }

    [Obsolete]
    private void AutoSwipeCarousel()
    {
        Device.StartTimer(TimeSpan.FromSeconds(7), () =>
        {
            if (IsNewsExist == true)
            {
                CurrentCarouselIndex = (CurrentCarouselIndex + 1) % CarouselNewsList.Count;
                return true; // Return true to keep the timer running
            }
            else
            {
                return true; // Return true to keep the timer running

            }

        });
    }



}

Here is the cs code :

public partial class MyNewsPage : ContentPage
{
    private NewsViewModel _viewModel;

    [Obsolete]
    public MyNewsPage()
    {
        InitializeComponent();
        _viewModel = new NewsViewModel(App.UserDatabase);
        BindingContext = _viewModel;
        // Add this line to bind the CarouselView's position
      //  newsCarousel.SetBinding(CarouselView.PositionProperty, new Binding(nameof(NewsViewModel.CurrentCarouselIndex), BindingMode.TwoWay));

    }

    [Obsolete]
    void OnShowBottonSheetFilterCountry(System.Object sender, System.EventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(async () =>
           {

               var page = new NewsListCountryBottomSheet();
               page.HasHandle = false;
               await page.ShowAsync(Window);
           });

                   MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.ChangeCountryNews.ToString());

    }

    [Obsolete]
    void OnShowBottonSheetFilterNews(System.Object sender, System.EventArgs e)
    {

        var viewModel = BindingContext as NewsViewModel;
        MainThread.BeginInvokeOnMainThread(async () =>
{

    var page = new NewsFilterCategoryBottomSheet(viewModel.UserNewsLanguageCode, viewModel.CategoryToFilter);
    page.HasHandle = false;
    await page.ShowAsync(Window);
});

        MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.FilteredNews.ToString());

    }


    UserNewsReadModel usernewsread;
    async void OnNewsItemTapped(System.Object sender, System.EventArgs e)
    {
        var tappedItem = (sender as Border).BindingContext as NewsModel;


        if (tappedItem != null && !string.IsNullOrEmpty(tappedItem.NewsUrl))
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {

                usernewsread = new UserNewsReadModel();
                usernewsread.UserId = Preferences.Default.Get("MyUserId", "");
                usernewsread.Language = tappedItem.Language;
                usernewsread.NewsName = tappedItem.NewsName;
                usernewsread.NewsUrl = tappedItem.NewsUrl;
                usernewsread.NewsProvider = tappedItem.NewsProvider;
                usernewsread.NewsImageUrl = tappedItem.NewsImageUrl;
                usernewsread.NewsDate = tappedItem.NewsDate;
                usernewsread.NewsCategory = tappedItem.NewsCategory;
                usernewsread.LeafProvider = tappedItem.LeafProvider;

                var page = new NewsBottomSheet(usernewsread);
                page.HasHandle = false;
                await page.ShowAsync(Window);
            });

                    MyFunctionShared.SetAppActivity(
MyVariablesClassApp.AppMenu.News.ToString(),
MyVariablesClassApp.AppSubMenu.SeenNews.ToString());
        }
    }


    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();

        // Subscribe to the visibility changes
        _viewModel.PropertyChanged += ViewModel_PropertyChanged;
    }

    private async void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(NewsViewModel.IsSearchingNews))
        {
            if (_viewModel.IsSearchingNews)
            {
                await NewsMenuLayout.FadeTo(0, 250);
            }
            else
            {
                await NewsMenuLayout.FadeTo(1, 250);
            }
        }

    }

    /*
        private void OnSearchTextChanged(object sender, TextChangedEventArgs e)
        {
            _viewModel.FilterNewsList(e.NewTextValue);
        }*/





}

Here is the function to load the data :

    int NumberAddedNews = 0;//Allow to add news in Carrousel
    private async Task LoadNewsAsync()
    {
        IsLoading = true;

        try
        {
            await GetLocalDB();
            UserNewsLanguageCode = MyMvvMuser.NewsLanguage;

            _currentOffset = 0;
            var MyNewsData = await NewsDataAPIManager.LoadNewsDataAsync(UserNewsLanguageCode, CategoryToFilter, _currentOffset, _limit);

            IsNewsExist = MyFunctionShared.IsListNotNullOrEmpty(MyNewsData);


            await MainThread.InvokeOnMainThreadAsync(() =>
               {
                   
                   NewsList.Clear();
                   CarouselNewsList.Clear();

                   if (IsNewsExist)
                   {

                       foreach (var nw in MyNewsData)
                       {
                           if (NumberAddedNews <= 3)
                           {
                               CarouselNewsList.Add(nw); // got an error here when receiveing the message
                           }
                           else
                           {
                               NewsList.Add(nw);
                           }

                           NumberAddedNews++;

                       }

                       _currentOffset += _limit;

                   }

               });





        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.WriteLine($"Error loading cards: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
        }
    }



To reload the data I receive a message so that the data are reloaded : 

      // Subscribe to the NewsCountrySelectedMessage
        WeakReferenceMessenger.Default.Register<NewsCountrySelectedMessage>(this, async (r, m) =>
        {
            UserNewsLanguageCode = m.Value.Code;
            NumberAddedNews = 0;
            ImageFiltered = "filterblack";
            CategoryToFilter = string.Empty;
            MyMvvMuser.NewsLanguage = UserNewsLanguageCode;
            LoadNewsCommand.Execute(null);


        });

My Problem : The reload work well on IOS but not on Android the app crash at the line " CarouselNewsList.Add(nw);" of the function LoadNewsAsync. I think it is a UI Issue and I do not see any error triggered

本文标签: netMAUIIssue with CarrouselView when adding itemStack Overflow