简体   繁体   中英

Callback to ContentPage from helper class event listener

I have a simple Xamarin Forms project to test interaction with a Firebase Realtime Database. It includes a main page, with buttons to add,edit,delete and query a database. A Firebase helper class contains all the code to perform those actions, as well as an observable subscription to fire an event when data is added,updated or deleted. I need the "ShowData" method called by the observable event to make a callback to the ContentPage to refresh a list.

I'm not sure how to accomplish this. I thought I could add a delegate method to the ContentPage, but didn't know how to code it in the page.

Any help is greatly appreciated.

Firebase helper class

using System;
using System.Collections.Generic;
using XamarinFirebase.Model;
using Firebase.Database;
using Firebase.Database.Query;
using System.Linq;
using System.Threading.Tasks;
using Firebase.Database.Streaming;
using Xamarin.Forms;

namespace XamarinFirebase.Helper
{

    public class FirebaseHelper
    {
        FirebaseClient firebase = new FirebaseClient("https://xamarinfirebase-bdc74.firebaseio.com/");
        bool init = false;
        int status = 0;

        public void ShowData(FirebaseEvent<Person> e)
        {
            try
            {
                switch (e.EventType)
                {
                    case FirebaseEventType.Delete:
                        if (status == 4)
                        {
                            Device.BeginInvokeOnMainThread(async () =>
                            {
                                await Application.Current.MainPage.DisplayAlert("Deleted", e.EventSource.GetType().ToString() + " - " + e.Object.Name, "OK");
                            });
                        }
                        break;
                    case FirebaseEventType.InsertOrUpdate:
                        if (status == 2)
                        {
                            Device.BeginInvokeOnMainThread(async () =>
                            {
                                await Application.Current.MainPage.DisplayAlert("Added", e.EventSource.GetType().ToString() + " - " + e.Object.Name, "OK");
                            });
                        }
                        if (status == 3)
                        {
                            Device.BeginInvokeOnMainThread(async () =>
                            {
                                await Application.Current.MainPage.DisplayAlert("Updated", e.EventSource.GetType().ToString() + " - " + e.Object.Name, "OK");
                            });
                        }
                        break;
                    default:
                        Device.BeginInvokeOnMainThread(async () =>
                        {
                            await Application.Current.MainPage.DisplayAlert("Unknown", e.EventSource.GetType().ToString() + " - " + e.Object.Name, "OK");
                        });
                        break;
                }

                status = 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<List<Person>> GetAllPersons()
        {
            if (!init)
            {
                var observable = firebase
                    .Child("Persons")
                    .AsObservable<Person>()
                    .Subscribe(d => ShowData(d));

                init = true;
            }

            status = 1;

            return (await firebase
              .Child("Persons")
              .OnceAsync<Person>()).Select(item => new Person
              {
                  Name = item.Object.Name,
                  PersonId = item.Object.PersonId
              }).ToList();
        }

        public async Task<Person> GetPerson(int personId)
        {
            status = 1;

            var allPersons = await GetAllPersons();
            await firebase
              .Child("Persons")
              .OnceAsync<Person>();
            return allPersons.Where(a => a.PersonId == personId).FirstOrDefault();
        }

        public async Task AddPerson(int personId,string name)
        {
            status = 2;

            await firebase
              .Child("Persons")
              .PostAsync(new Person() { PersonId=personId, Name = name });
        }

        public async Task UpdatePerson(int personId, string name)
        {
            status = 3;

            var toUpdatePerson = (await firebase
              .Child("Persons")
              .OnceAsync<Person>()).Where(a => a.Object.PersonId == personId).FirstOrDefault();

            await firebase
              .Child("Persons")
              .Child(toUpdatePerson.Key)
              .PutAsync(new Person() { PersonId = personId, Name = name });
        }

        public async Task DeletePerson(int personId)
        {
            status = 4;

            var toDeletePerson = (await firebase
              .Child("Persons")
              .OnceAsync<Person>()).Where(a => a.Object.PersonId == personId).FirstOrDefault();
            await firebase.Child("Persons").Child(toDeletePerson.Key).DeleteAsync();

        }
    }

}

ContentPage

using System;
using Xamarin.Forms;
using XamarinFirebase.Helper;

namespace XamarinFirebase
{
    public partial class MainPage : ContentPage
    {
        FirebaseHelper firebaseHelper = new FirebaseHelper();

        public MainPage()
        {
            InitializeComponent();
        }

        protected async override void OnAppearing()
        {

            base.OnAppearing();
            var allPersons = await firebaseHelper.GetAllPersons();
            lstPersons.ItemsSource = allPersons;
        }

        private async void BtnAdd_Clicked(object sender, EventArgs e)
        {
            try
            {
                await firebaseHelper.AddPerson(Convert.ToInt32(txtId.Text), txtName.Text);
                txtId.Text = string.Empty;
                txtName.Text = string.Empty;
                var allPersons = await firebaseHelper.GetAllPersons();
                lstPersons.ItemsSource = allPersons;
            }
            catch (Exception)
            {

                throw;
            }
        }

        private async void BtnRetrive_Clicked(object sender, EventArgs e)
        {
            try
            {
                var person = await firebaseHelper.GetPerson(Convert.ToInt32(txtId.Text));
                if (person != null)
                {
                    txtId.Text = person.PersonId.ToString();
                    txtName.Text = person.Name;

                }
                else
                {
                    await DisplayAlert("Success", "No Person Available", "OK");
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        private async void BtnUpdate_Clicked(object sender, EventArgs e)
        {
            try
            {
                await firebaseHelper.UpdatePerson(Convert.ToInt32(txtId.Text), txtName.Text);
                txtId.Text = string.Empty;
                txtName.Text = string.Empty;
                var allPersons = await firebaseHelper.GetAllPersons();
                lstPersons.ItemsSource = allPersons;
            }
            catch (Exception)
            {

                throw;
            }
        }

        private async void BtnDelete_Clicked(object sender, EventArgs e)
        {
            try
            {
                await firebaseHelper.DeletePerson(Convert.ToInt32(txtId.Text));
                var allPersons = await firebaseHelper.GetAllPersons();
                lstPersons.ItemsSource = allPersons;
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}

Xamarin Forms Messaging Center can do this for you

Subscribe for a Message in your contentPage:

MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) => {
// Your code here
});

Then throw a message on to the content page something like:

MessagingCenter.Send<MainPage> (this, "Hi"); 

The string doesn't change - it indicates the message type and is used for determining which subscribers to notify. This sort of message is used to indicate that some event occurred, such as "upload completed", where no further information is required.

NOTE in both cases this is the MainPage instance.

For a better understanding check Messaging Center

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