Home > Software design >  How do I set the content of a ListView to a new ObservableCollection?
How do I set the content of a ListView to a new ObservableCollection?

Time:10-04

I want to display data in a ListView in Xamarin forms.

I get a set of items (RückmeldeItems) from my API, which depends on a unique ID, when I open the ListViewPage.
I want the ListView to only show the new set of items.
Currently it is showing the items that were loaded, when the page appeared the first time. When I reload it, I want the ListView to contain the new set of items and delete the old set.

I tried implementing it by assingning a new List<RückmeldeItems> to the BindingContext of the ListView, however this doesn´t work. This error is documented on Microsoft Docs for ListViews

I also tried to Clear() it and then assign the element one by one, using Add(rückmeldeItem) to no avail.

How can I make the ListView contain the correct set of items?

The IList, which the Content is bound to:

public IList<RückmeldeItem> rückmeldeItems { get; private set; }

The Method used to fill the ListView aka the BindingContext (I commented the not working attempt out):

private void FillListView(List<RückmeldeItem> rückmeldeItemsList)
        {
            if(rückmeldeItems == null)
            {
                rückmeldeItems = rückmeldeItemsList;
            }
            //rückmeldeItems.Clear();
            /*foreach (RückmeldeItem rückmeldeItem in rückmeldeItemsList)
            {
                rückmeldeItems.Add(rückmeldeItem);

                //DisplayAlert(rückmeldeItem.RückmeldeNummer.ToString(), rückmeldeItem.Status, "OK");
            }*/

            BindingContext = this;
        }

The method which fetches the RückmeldeItems(simplified for oversight, but it returns a working List<RückmeldeItem>)

private async Task<List<RückmeldeItem>> GetRNRs()
        {
            
            List<RückmeldeItem> rückmeldeItemsList = ...the code fetching the RückmeldeItems...;
            return rückmeldeItemsList;
        }

The method which is called whenever the Page appears. Calls the other methods:

 private async void EventPage_OnAppearing(object sender, EventArgs e)
        {
            List<RückmeldeItem> rückmeldenummern = await GetRNRs();
            FillListView(rückmeldenummern);
        }

EDIT: I want to Display 3 Attributes in a custom style. The best way to do this seemed to be with data bindings, however I got the suggestion to manually set the ItemsSource.
How can I keep this custom Layout when I set the source manually?

The xaml in question:

                    <ListView x:Name="ListViewRückmeldenummern" ItemTapped="ListViewRückmeldenummern_ItemTapped" RowHeight="80" ItemsSource="{Binding rückmeldeItems}" VerticalScrollBarVisibility="Always">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <Grid >
                                        <Label Text="{Binding RückmeldeNummer}" Grid.Row="0" Grid.RowSpan="2" TextColor="Black" FontSize="Large" FontFamily="Hansom" Grid.Column="0" Margin="10,15,0,15"/>
                                        <Label Text="{Binding Artikelbezeichnung}" Grid.Row="0" TextColor="#888888" FontSize="Small" FontFamily="Hansom" Grid.Column="1" Margin="0,15,10,0" HorizontalTextAlignment="End"/>
                                        <Label Text="{Binding Status}" Grid.Row="1" TextColor="#888888" FontSize="Small" FontFamily="Hansom" Grid.Column="1" Margin="0,0,10,15" HorizontalTextAlignment="End"/>
                                    </Grid>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

CodePudding user response:

Manually setting the ItemsSource made it work! Answered this myself so the I can close the question in 3 days. Credits go to Jason.

The new method:

private void FillListView(ObservableCollection<RückmeldeItem> rückmeldeItemsList)
        {
            ListViewRückmeldenummern.ItemsSource = rückmeldeItemsList;
            BindingContext = this;
        }
  • Related