Search code examples
c#xamlobservablecollectionmauicollectionview

CollectionView doesn't update with ObservableCollection as Sourcee


I have a CollectionView in A ScrollView. I want to bind the Soource to a ObservableCollection in my ViewModel.

Here's the Code of my Xaml:

<RefreshView x:DataType="vm:TodayViewModel" Command="{Binding LoadStandInsCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
                <CollectionView ItemsSource="{Binding StandIns}" SelectionMode="None">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <StackLayout Padding="10" x:DataType="model:StandIn" BackgroundColor="Red">
                                <Frame HeightRequest="50" >
                                    <StackLayout>
                                        <Label Style="{StaticResource BaseLabel}" Text="{Binding Stunde}" FontSize="10"/>
                                        <Label Style="{StaticResource BaseLabel}" Text="{Binding Fach}" FontSize="10"/>
                                        <Label Style="{StaticResource BaseLabel}" Text="{Binding Raum}" FontSize="10"/>
                                        <Label Style="{StaticResource BaseLabel}" Text="{Binding Lehrer}" FontSize="10"/>
                                        <Label Style="{StaticResource BaseLabel}" Text="{Binding Art}" FontSize="10"/>
                                    </StackLayout>
                                </Frame>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </RefreshView>

Here's my Xaml.cs:

TodayViewModel _viewModel;
public TodayPage()
{
    InitializeComponent();
    BindingContext = _viewModel = new TodayViewModel();
}

protected override void OnAppearing()
{
    base.OnAppearing();
    _viewModel.OnAppearing();
}

Here's my View Model:

  public Command LoadStandInsCommand { get; }
    public ObservableCollection<StandIn> StandIns { get; }
public TodayViewModel()
        {
            StandIns = new ObservableCollection<StandIn>();
            LoadStandInsCommand = new Command(async ()=> await ExecuteLoadStandInsCommand());
        }

async Task ExecuteLoadStandInsCommand()
        {
            IsBusy = true;
            try
            {
                StandIns.Clear();
                if (loadListToday)
                {
                    sIList.AddRange(gh.GetStandInsToday());
                }
                else
                {
                    sIList.AddRange(gh.GetStandInsTomorrow());
                }
                foreach (StandIn item in sIList)
                {
                    if (item.Klasse == pN.Klasse || item.Lehrer == pN.Klasse)
                    {
                        StandIns.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }

As a info I'm writting a .netMaui App. The Problem is that the CollectionView doesn't show any Items, but StandIns is filled with 39 Items. I don't know why it's not working. Thanks for helping me.


Solution

  • I tested your code and did some improvements. It can work now.

    Here's the Code of my Xaml:

    <RefreshView x:DataType="vm:TodayViewModel" Command="{Binding LoadStandInsCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
        <CollectionView ItemsSource="{Binding StandIns}"  SelectionMode="None">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Padding="10"  BackgroundColor="Red">
                        <!-- I changed the style format you can change the label style here-->
                        <StackLayout.Resources>
                            <!-- Implicit style -->
                            <Style TargetType="Label">
                                <Setter Property="FontSize" Value="14" />
                                <Setter Property="BackgroundColor" Value="#1976D2" />
                                <Setter Property="TextColor" Value="White" />
                            </Style>
                        </StackLayout.Resources>
    
                        <Frame HeightRequest="200" >
                            <StackLayout>
                                <Label  Text="{Binding Stunde}" FontSize="20"/>
                                <Label  Text="{Binding Fach}" FontSize="20"/>
                                <Label  Text="{Binding Raum}" FontSize="20"/>
                                <Label  Text="{Binding Lehrer}" FontSize="20"/>
                                <Label  Text="{Binding Art}" FontSize="20"/>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </RefreshView>
    

    Here is the code in Xaml.cs:

      public MainPage()
        {
            InitializeComponent();
            
            BindingContext = new TodayViewModel();
        }
    

    I used the static data to test and you can remove them. Here is the code in my ViewModel:

     internal class TodayViewModel
        {
           /* public Command LoadStandInsCommand { get; }*/
            public ObservableCollection<StandIn> StandIns { get;  }
            public TodayViewModel()
            {
                StandIns = new ObservableCollection<StandIn>();
    
                StandIns.Add(new StandIn() { Art = "art1", Fach = "fach1", Lehrer = "lehrer1", Raum = "raum1", Stunde = "stunde1" });
                StandIns.Add(new StandIn() { Art = "art1", Fach = "fach1", Lehrer = "lehrer1", Raum = "raum1", Stunde = "stunde1" });
                StandIns.Add(new StandIn() { Art = "art1", Fach = "fach1", Lehrer = "lehrer1", Raum = "raum1", Stunde = "stunde1" });
                StandIns.Add(new StandIn() { Art = "art1", Fach = "fach1", Lehrer = "lehrer1", Raum = "raum1", Stunde = "stunde1" });
                /*  LoadStandInsCommand = new Command(async () => await ExecuteLoadStandInsCommand());*/
    
    
            }
    
          /*  async Task ExecuteLoadStandInsCommand()
            {
                IsBusy = true;
                try
                {
                    StandIns.Clear();
                    if (loadListToday)
                    {
                        sIList.AddRange(gh.GetStandInsToday());
                    }
                    else
                    {
                        sIList.AddRange(gh.GetStandInsTomorrow());
                    }
                    foreach (StandIn item in sIList)
                    {
                        if (item.Klasse == pN.Klasse || item.Lehrer == pN.Klasse)
                        {
                            StandIns.Add(item);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
                finally
                {
                    IsBusy = false;
                }
            }*/
        }
    

    Here is my Model:

      internal class StandIn
        {
            public string Stunde { get; set; }
            public string Fach { get; set; }
            public string Raum { get; set; }
            public string Lehrer { get; set; }
            public string Art { get; set; }
        }
    

    This is the final view of the project:

    enter image description here