listviewdata-bindingxamarin.formstabbedpage

ListView contained in a TabbedPage not updating from Binding


In the following code im binding Records form a viewmodel , which is using an observablecollection , im also raising the inotifypropertychange , now i have a button setup which uses the navigation.pushasync method to go to a new page , over there im updating the database Records , i have created a listview in this new page and used the same binding shown here to bind the Records , whenever i add something it updates , but if i press the back button and come back to this EntryTabPage the binding doesnt update , it only updates if i close the app fully and restart it the data is shown.

I want this listview to be updated not sure how to do it , i have tried using the onappearing and typing in the Listviewname.itemssource=Records; but this is showing an error "this does not exist in the current context" any help in the right direction would be appreciated.

Note:The binding is working elsewhere except within the tabbed page. This is the Hierarchy TabbedPage->ContentPage->StackLayout->ListView (it is in this list view that the binding doesn't get updated.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Bunk_Master.EntryPageTab1"
         Title="Default">
<StackLayout x:Name="stacklayout">
    <ListView ItemsSource="{Binding Records}"
              x:Name="classListView">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextCell Text="{Binding}">

                </TextCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Text="new" 
            x:Name="addclassbutton">

    </Button>


</StackLayout>

namespace Bunk_Master
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class EntryPageTab1 : ContentPage
    {

        public EntryPageTab1()
        {
            InitializeComponent();
            BindingContext = new ClassViewModel();



            addclassbutton.Clicked += async (object sender, EventArgs e) =>
             {
                 await this.Navigation.PushAsync(new AddClass());
             };


        }

              protected override void OnAppearing()
        {


            base.OnAppearing();


        }



    }



    }

This the the ViewModel

    namespace Bunk_Master
{
    public class ClassViewModel : BaseViewModel
    {


        readonly Database db;
        public string classname { get; set; }
       // public int absentnos { get; set; }
      //  public int presentnos { get; set; }

        public ICommand AddCommand { get; set; }
        public ICommand DeleteCommand { get; set; }

        public ObservableCollection<string> Records { get; set; }


        public ClassViewModel()
        {
            AddCommand = new Command(Add);
            DeleteCommand = new Command(Delete);

            db = new Database("classdb");
            db.CreateTable<ClassModel>();
            Records = new ObservableCollection<string>();
            ShowAllRecords();
        }



        void Add()
        {
            var record = new ClassModel
            {
                classname = classname,
                //absentnum = absentnos,
                //presentnum = presentnos
            };
            db.SaveItem(record);
            Records.Add(record.ToString());
            RaisePropertyChanged(nameof(Records));
            ClearForm();

        }

        private void Delete(object obj)
        {
            throw new NotImplementedException();
        }

        void ClearForm()
        {
            classname = string.Empty;

            RaisePropertyChanged(nameof(classname));
        }

        void ShowAllRecords()
        {
            Records.Clear();
            var classdb = db.GetItems<ClassModel>();
            foreach (var classmodel in classdb)
            {
                Records.Add(classmodel.ToString());
            }
        }
    }
}

This is where i implement the Inotifypropertychange

namespace Bunk_Master
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler == null) return;
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Solution

  • If anyone happens to find a class working in one class but not in another class and your code is perfect, its just because the class you instantiated must be used instead of instantiating a new one.

    Just adding this line fixed my code

    public static Workingclass classInstance = new Workingclass;
    

    Then i used the classIncstance instead of creating new instances , in other classes and the data was updating properly.

    Note:I wanted to delete this post but there were a lot of other similar posts on the internet without anyone addressing the simple issue maybe someone can find it useful.