Search code examples
classlistviewxamarin.formsitemsource

How to update list view from another class in Xamarin forms?


I have created a list view in one class and called delete method from another class. Listview getting call but not updating list view if i call from another class. But its getting update when i call inside the same class. How to solve this issue?

namespace New
{
    public partial class WishesPage : ContentPage
    {
        ListView listView = new ListView();

        public WishesPage()
        {
            InitializeComponent();

            var arr = JToken.Parse(ids);

            foreach (var ite in arr.Children())
            {
                var itemProperties = ite.Children<JProperty>();
                string contactElement = itemProperties.FirstOrDefault(x => x.Name == "contact").Value.ToString();
                sample.Add(contactElement);
            }

            listView.ItemTemplate = new DataTemplate(typeof(CustomListCell));
            listView.ItemsSource = sample;

            Content = new StackLayout
            {
                Children =
                {
                    listView,
                }
            };
        }

        public async Task delete(string wishid)
        {
            indicator.IsRunning = true;

            var client = new HttpClient();
            client.BaseAddress = new Uri("http:……”);

            if (response == "success")
            {
                listView.ItemsSource = null;
                listView.ItemsSource = sample;
            }
        }
    }

    public class CustomListCell : ViewCell
    {
        public CustomListCell()
        {
              wishIdLabel.SetBinding(Label.TextProperty, new Binding("contact"));

            horizontalLayout.Children.Add(wishIdLabel);

            var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true };
            deleteAction.Clicked += async (sender, e) =>
            {
                WishesPage wishes = new WishesPage();
                wishes.delete(wishId);
            };
            ContextActions.Add(deleteAction);
        }
    }
}

Solution

  • I have updated this repo that explain how to use Commands inside a ViewCell.

    In your case, you should move the construction of ViewCell inside the ContentPage. Something like

            lv.ItemTemplate = new DataTemplate(() =>
            {
    
                StackLayout slView = new StackLayout();
    
                Label lDesc = new Label();
                lDesc.SetBinding(Label.TextProperty, "Description", stringFormat: "DESCRIPTION: {0}");
    
                var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
                deleteAction.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.TrashCommand", source: this));
                deleteAction.SetBinding(MenuItem.CommandParameterProperty, ".");
    
                slView.Children.Add(lDesc);
    
                ViewCell vc = new ViewCell() {View = slView };
                vc.ContextActions.Add(deleteAction);
    
                return vc;
            }
    

    Now, when you longpress the row, a ContextAction "Delete" appears and a TrashCommand in your ViewModel is executed (you should use MVVM...), a "these" parameter is passed (the selected obj) so you can delete it from the List

            this.TrashCommand = new Command(async (object obj) => {
    
                try
                {
                    if (_isTapped)
                        return;
    
                    if (obj != null)
                        System.Diagnostics.Debug.WriteLine("Obj is not null");
                    else
                        System.Diagnostics.Debug.WriteLine("Obj IS null");
    
    
                    _isTapped = true;
                    var ret = await Application.Current.MainPage.DisplayAlert("Attention", "Delete this row?", "Yes", "No");
    
                    if (ret)
                    {
    
                        // List is your "sample" list... Removing the obj, is it reflected to ListView if you use ObservableCollection instead of List
                        List.Remove((Model)obj);
                        Count = List.Count;
                    }
    
                    _isTapped = false;
    
                }
                catch (Exception ex) {
                    _isTapped = false;
                    await Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
                }
            });
        }