最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

.net - MAUI : Issue with CarrouselView when adding item - Stack Overflow

matteradmin5PV0评论

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

Post a comment

comment list (0)

  1. No comments so far