简体   繁体   中英

Xamarin.Forms listview not updating in Android

After searching every forum online I decided to post my own question: My listview data is shown correctly in IOS but not in Android. I'm binding to a property in my view model and that looks correct but I can't figure out what I'm missing (I'm trying to get a list of orders to populate my listview). Any help is appreciated!

Also, I'm using a tabbed page layout. Not sure if that makes a difference or not.

//View model
public ObservableCollection<GroupedOrderModel> ListOfOrdersGrouped
{

            get { return listOfOrdersGrouped; }
            set {
                listOfOrdersGrouped = value;
                NotifyPropertyChanged("listOfOrdersGrouped");
            }
        }

    public class OrderList : List<OrderStatusInfo>
    {
        public string Heading { get; set; }
        public List<OrderStatusInfo> Orders
        {
            get { return this; }
            set { Orders = value; }
        }
    }

public async Task<bool> BuildListviewData()
{

       await Task.Run(()=> {
          ObservableCollection<GroupedOrderModel> orderList = new ObservableCollection<GroupedOrderModel>();

         if (GlobalInfo.GlobalOrderList != null && GlobalInfo.GlobalOrderList.Count > 0)
          {    

                  List<string> Headers = GlobalInfo.GlobalOrderList.Select(x => x.Status).Distinct().OrderBy(x => x).ToList();

                   foreach (var item in Headers)
                   {
                       var oGroup = new GroupedOrderModel
                       {
                           Heading = item
                       };

                       var oList = GlobalInfo.GlobalOrderList.Where(x => x.Status == item).ToList();
                       foreach (var o in oList)
                          oGroup.Add(o);

                          orderList.Add(oGroup);
                     }

                ListOfOrdersGrouped = orderList;

          }
      }
}

   //Orders.cs page
   protected async override void OnAppearing()


   {

         await ovm.BuildListviewData();
         BindingContext = ovm;        
         base.OnAppearing();
   }
//The XAML

                 <ListView x:Name="ListViewOrdersList" HasUnevenRows="True" ItemsSource="{Binding ListOfOrdersGrouped}" IsGroupingEnabled="True">
                    <ListView.GroupHeaderTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Label Text="{Binding Heading}" Margin="10"/>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.GroupHeaderTemplate>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid Padding="10">
                                    <Label Text="{Binding OrderNo}" FontSize="20" HorizontalOptions="Start"/>
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

Change your ItemSource property's to

private listOfOrdersGrouped;
public ObservableCollection ListOfOrdersGrouped
{

    get { return listOfOrdersGrouped; }
    set {
        listOfOrdersGrouped = value;
        NotifyPropertyChanged("ListOfOrdersGrouped");
    }
}

The NotifyPropertyChanged should be:

NotifyPropertyChanged("ListOfOrdersGrouped");

So that the name matches that of the property your binding to in the XAML.

For anyone struggling with the same problem:

The problem ended up being an issue with my view model being page specific (Such as OrdersViewModel.cs for my Orders.xaml.cs page). After I created an AppViewModel.cs for my App.xaml.cs page and dumped my OrdersViewModel properties in there under a new class named OrdersViewModel it all worked since the project runs the App.xaml and App.xaml.cs pages on startup before it does anything else. That's why binding was working in IOS and not Android. Android was attempting to process all code for every tabbed page before the binding could finish being instantiated (therefore, no data shown!).

However, I did tweak my code a little. Here are the changes:

namespace MyApp.ViewModels
{
    public class AppViewModel
    {
        public OrdersViewModel Ovm { get; set; }
    }

    public class OrdersViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<GroupedOrderModel> ListOfOrdersGrouped
        {
            get { return listOfOrdersGrouped; }
            set
            {
                listOfOrdersGrouped = value;
                NotifyPropertyChanged("ListOfOrdersGrouped");
            }
        }

        public async Task<bool> BuildListviewData() 
        {
            //Same code here as mentioned above
        }
    }

     //Deleted OrderList class mentioned above

    public class GroupedOrderModel : ObservableCollection<OrderStatusInfo>
    {
        public string Heading { get; set; }
    }
}


//Xaml
<ListView x:Name="ListViewOrdersList" HasUnevenRows="True" ItemsSource="{Binding Ovm.ListOfOrdersGrouped}" IsGroupingEnabled="True">
     <ListView.GroupHeaderTemplate>
            <DataTemplate>
                  <ViewCell>
                      <Label Text="{Binding Heading}" Margin="10"/>
                   </ViewCell>
            </DataTemplate>
      </ListView.GroupHeaderTemplate>
      <ListView.ItemTemplate>
            <DataTemplate>
                 <ViewCell>
                     <Grid Padding="10">
                        <Label Text="{Binding OrderNo}" FontSize="20" HorizontalOptions="Start"/>
                      </Grid>
                 </ViewCell>
             </DataTemplate>
       </ListView.ItemTemplate>
</ListView>

Happy coding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM