消息中心
您可能不喜欢两个页面类直接相互调用方法的想法。 它似乎适用于小样本,但对于具有大量类间通信的大型程序,您可能更喜欢一些不需要实际页面实例的更灵活的东西。
这样的工具是Xamarin.Forms MessagingCenter类。 这是一个静态类,有三个方法,分别是Subscribe,Unsubscribe和Send。 消息使用文本字符串标识,并且可以包含任何对象。 Send方法广播任何订户收到的消息。
DataTransfer2程序具有与DataTransfer1相同的Information类和相同的XAML文件,但它使用MessagingCenter类而不是直接方法调用。
主页的构造函数订阅由文本字符串“InformationReady”标识的消息.Subging的通用参数指示哪个对象类型发送此消息 - 类型为DataTransfer2InfoPage的对象 - 以及数据类型,即信息。 Subscribe方法参数指示接收消息的对象(this),消息名称和lambda函数。 此lambda函数的主体与上一个程序中InformationReady方法的主体相同:
public partial class DataTransfer2HomePage : ContentPage
{
ObservableCollection<Information> list = new ObservableCollection<Information>();
public DataTransfer2HomePage()
{
InitializeComponent();
// Set collection to ListView.
listView.ItemsSource = list;
// Subscribe to "InformationReady" message.
MessagingCenter.Subscribe<DataTransfer2InfoPage, Information>
(this, "InformationReady", (sender, info) =>
{
// If the object has already been added, replace it.
int index = list.IndexOf(info);
if (index != -1)
{
list[index] = info;
}
// Otherwise, add it.
else
{
list.Add(info);
}
});
}
// Button Clicked handler.
async void OnGetInfoButtonClicked(object sender, EventArgs args)
{
await Navigation.PushAsync(new DataTransfer2InfoPage());
}
// ListView ItemSelected handler.
async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs args)
{
if (args.SelectedItem != null)
{
// Deselect the item.
listView.SelectedItem = null;
DataTransfer2InfoPage infoPage = new DataTransfer2InfoPage();
await Navigation.PushAsync(infoPage);
// Send "InitializeInfo" message to info page.
MessagingCenter.Send<DataTransfer2HomePage, Information>
(this, "InitializeInfo", (Information)args.SelectedItem);
}
}
}
ListView的ItemSelected处理程序包含对MessagingCenter.Send的调用。 泛型参数指示消息发送方的类型和数据类型。 该方法的参数指示发送消息的对象,消息名称和数据,它是ListView的SelectedItem。
DataTransfer2InfoPage代码隐藏文件包含对MessagingCenter.Subscribe和MessageCenter.Send的补充调用。 信息页面构造函数订阅“InitializeInfo”消息; lambda函数的主体与前一个程序中的InitializeInfo方法相同,只是它以取消订阅消息结束。 取消订阅可确保不再引用信息页面对象,并允许对信息页面对象进行垃圾回收。 但是,严格来说,不应该取消订阅,因为MessagingCenter为订阅者维护WeakReference对象:
public partial class DataTransfer2InfoPage : ContentPage
{
// Instantiate an Information object for this page instance.
Information info = new Information();
public DataTransfer2InfoPage()
{
InitializeComponent();
// Subscribe to "InitializeInfo" message.
MessagingCenter.Subscribe<DataTransfer2HomePage, Information>
(this, "InitializeInfo", (sender, info) =>
{
// Replace the instance.
this.info = info;
// Initialize the views.
nameEntry.Text = info.Name ?? "";
emailEntry.Text = info.Email ?? "";
if (!String.IsNullOrWhiteSpace(info.Language))
{
languagePicker.SelectedIndex = languagePicker.Items.IndexOf(info.Language);
}
datePicker.Date = info.Date;
// Don't need "InitializeInfo" any more so unsubscribe.
MessagingCenter.Unsubscribe<DataTransfer2HomePage, Information>
(this, "InitializeInfo");
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
// Set properties of Information object.
info.Name = nameEntry.Text;
info.Email = emailEntry.Text;
int index = languagePicker.SelectedIndex;
info.Language = index == -1 ? null : languagePicker.Items[index];
info.Date = datePicker.Date;
// Send "InformationReady" message back to home page.
MessagingCenter.Send<DataTransfer2InfoPage, Information>
(this, "InformationReady", info);
}
}
OnDisappearing覆盖比前一个程序中的版本短得多。 要在主页中调用方法,以前的程序必须进入NavigationStack集合。 在这个版本中,所有必要的是使用MessagingCenter.Send向订阅它的人发送“InformationReady”消息,这恰好是主页。