第二十四章:页面导航(十一)

简介: 消息中心您可能不喜欢两个页面类直接相互调用方法的想法。 它似乎适用于小样本,但对于具有大量类间通信的大型程序,您可能更喜欢一些不需要实际页面实例的更灵活的东西。这样的工具是Xamarin.Forms MessagingCenter类。

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

目录
相关文章
|
7月前
|
小程序
【微信小程序】-- 页面导航 -- 编程式导航(二十三)
【微信小程序】-- 页面导航 -- 编程式导航(二十三)
|
7月前
|
小程序 API
【微信小程序】-- 页面导航 -- 声明式导航(二十二)
【微信小程序】-- 页面导航 -- 声明式导航(二十二)
|
前端开发
前端学习笔记202305学习笔记第二十二天-菜单路由和面包屑1
前端学习笔记202305学习笔记第二十二天-菜单路由和面包屑1
46 0
|
前端开发
前端学习笔记202305学习笔记第二十二天-菜单路由和面包屑2
前端学习笔记202305学习笔记第二十二天-菜单路由和面包屑2
63 0
|
Android开发 索引 iOS开发
第二十四章:页面导航(十七)
像现实生活中的应用程序理想情况下,用户在终止并重新启动应用程序时不应该知道。应用程序体验应该是连续且无缝的。即使程序没有一直运行,一个半月进入的条目从未完成也应该在一周后处于相同的状态。NoteTaker程序允许用户记录由标题和一些文本组成的注释。
548 0
|
XML JSON Android开发
第二十四章:页面导航(十五)
保存和恢复页面状态特别是当您开始使用多页面应用程序时,将应用程序的页面视为数据的主要存储库非常有用,而仅仅是作为底层数据的临时可视化和交互式视图。这里的关键词是暂时的。如果您在用户与之交互时保持基础数据是最新的,那么页面可以显示和消失而不必担心。
656 0
|
JavaScript 前端开发 Android开发
第二十四章:页面导航(十六)
保存和恢复导航堆栈 许多多页面应用程序的页面体系结构比DataTransfer6更复杂,您需要一种通用的方法来保存和恢复整个导航堆栈。此外,您可能希望将导航堆栈的保存与系统方式集成,以保存和恢复每个页面的状态,特别是如果您不使用MVVM。
499 0
|
JavaScript Android开发
第二十四章:页面导航(十四)
切换到ViewModel此时应该很明显,Information类应该真正实现INotifyPropertyChanged。 在DataTransfer5中,Information类已成为InformationViewModel类。
606 0
|
JavaScript Android开发 索引
第二十四章:页面导航(十三)
App类中介在Xamarin.Forms应用程序中,在公共代码项目中执行的第一个代码是通常名为App的类的构造函数,该类派生自Application。 在程序终止之前,此App对象保持不变,并且程序中的任何代码都可以通过静态Application.Current属性使用它。
516 0
|
Android开发 索引
第二十四章:页面导航(十二)
事件在方法调用方法和消息中心通信方法中,信息页面需要知道主页的类型。 如果可以从不同类型的页面调用相同的信息页面,这有时是不合需要的。这个问题的一个解决方案是info类实现一个事件,这就是DataTransfer3中采用的方法。
515 0