forms - 从帮助类事件监听器回调 ContentPage
问题描述
我有一个简单的 Xamarin Forms 项目来测试与 Firebase 实时数据库的交互。它包括一个主页,带有添加、编辑、删除和查询数据库的按钮。Firebase 帮助程序类包含执行这些操作的所有代码,以及在添加、更新或删除数据时触发事件的可观察订阅。我需要可观察事件调用的“ShowData”方法对 ContentPage 进行回调以刷新列表。
我不确定如何做到这一点。我以为我可以向 ContentPage 添加一个委托方法,但不知道如何在页面中对其进行编码。
任何帮助是极大的赞赏。
Firebase 助手类
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();
}
}
}
内容页
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 可以为您执行此操作
在您的 contentPage 中订阅消息:
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) => {
// Your code here
});
然后向内容页面发送一条消息,例如:
MessagingCenter.Send<MainPage> (this, "Hi");
该字符串不会更改 - 它指示消息类型并用于确定要通知哪些订阅者。此类消息用于指示发生了某些事件,例如“上传完成”,不需要进一步的信息。
注意在这两种情况下this
都是 MainPage 实例。
为了更好地理解检查消息中心
推荐阅读
- html - 如何在 HTML 的 div 中显示 XML 代码
- django - auth.views.Loginview 显示“__init__() 有一个意外的关键字参数 'request'”
- redirect - Sitecore - 类似 URL 的 301 重定向
- javascript - 根据 ID 设置元素的数据属性
- java - 我无法在 Spring 的后台运行该方法
- aspnetboilerplate - 使用 abp 的多语句事务中不允许创建数据库语句
- node.js - 来自 url 的参数添加到静态目录路径中
- r - 一列的值基于R中另一列的值
- mysql - 如何在 MySQL 中使用自定义逻辑 IF 语句比较两列之间的值
- python - SQLAlchemy 删除父级既不删除子级也不将子级 ForeignKey 值设置为 null