消息中心
您可能不喜欢两个页面类直接相互调用方法的想法. 它似乎适用于小样本, 但对于具有大量类间通信的大型程序, 您可能更喜欢一些不需要实际页面实例的更灵活的东西.
这样的工具是 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" 消息, 这恰好是主页.
来源: https://yq.aliyun.com/articles/699878