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

简介: 数据传输模式多页面应用程序中的页面通常需要共享数据,特别是一页面将信息传递到另一页面。 有时此过程类似于函数调用:当HomePage显示项目列表并导航到DetailPage以显示其中一个项目的详细视图时,HomePage必须将该特定项目传递给DetailPage。

数据传输模式

多页面应用程序中的页面通常需要共享数据,特别是一页面将信息传递到另一页面。 有时此过程类似于函数调用:当HomePage显示项目列表并导航到DetailPage以显示其中一个项目的详细视图时,HomePage必须将该特定项目传递给DetailPage。 或者当用户在FillOutFormPage中输入信息时,必须将该信息返回到调用FillOutFormPage的页面。
有几种技术可用于在页面之间传输数据。 您使用哪一个取决于具体的应用程序。 请记住,在整个讨论过程中,您可能还需要在应用程序终止时保存页面内容,并在程序重新启动时恢复内容。 一些数据共享技术比其他技术更有利于保存和恢复页面状态。 本章稍后将更详细地探讨此问题。
构造函数参数
当一个页面导航到另一个页面并需要将数据传递到该页面时,传递该数据的一种显而易见的方法是通过第二个页面的构造函数。
SchoolAndStudents计划说明了这种技术。 该程序使用了第19章“集合视图”中介绍的SchoolOfFineArt库。该程序由两个名为SchoolPage和StudentPage的页面组成。 SchoolPage类使用ListView显示学校中所有学生的可滚动列表。 当用户选择一个时,程序导航到显示有关个别学生的详细信息的学生页面。 该程序与第19章中的SelectedStudentDetail程序类似,不同之处在于列表和详细信息已分为两页。
这是SchoolPage。 为了使事情尽可能简单,ListView使用ImageCell显示学校中的每个学生:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SchoolAndStudents.SchoolPage"
             Title="School">

    <StackLayout BindingContext="{Binding StudentBody}">
        <Label Text="{Binding School}"
               FontSize="Large"
               FontAttributes="Bold"
               HorizontalTextAlignment="Center" />

        <ListView x:Name="listView"
                  ItemsSource="{Binding Students}"
                  ItemSelected="OnListViewItemSelected">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ImageCell ImageSource="{Binding PhotoFilename}"
                               Text="{Binding FullName}"
                               Detail="{Binding GradePointAverage,
                                                StringFormat='G.P.A. = {0:F2}'}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

此XAML文件中的数据绑定假定页面的BindingContext设置为SchoolOfFineArt库中定义的SchoolViewModel类型的对象。 SchoolViewModel具有StudentBody类型的属性,该属性设置为StackLayout的BindingContext。 Label绑定到StudentBody的School属性,ListView的ItemsSource绑定到StudentBody的Students集合属性。 这意味着ListView中的每个项都有一个Student类型的BindingContext。 ImageCell引用该Student对象的PhotoFilename,FullName和GradePointAverage属性。
这是在iOS,Android和Windows 10 Mobile上运行的ListView:
2019_04_23_095724
代码隐藏文件中的构造函数负责从SchoolViewModel的实例设置页面的BindingContext。 代码隐藏文件还包含ListView的ItemSelected事件的处理程序。 当用户点击其中一个学生时会触发此事件:

public partial class SchoolPage : ContentPage
{
    public SchoolPage()
    {
        InitializeComponent();
        // Set BindingContext.
        BindingContext = new SchoolViewModel();
    }
    async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs args)
    {
        // The selected item is null or of type Student.
        Student student = args.SelectedItem as Student;
        // Make sure that an item is actually selected.
        if (student != null)
        {
            // Deselect the item.
            listView.SelectedItem = null;
            // Navigate to StudentPage with Student argument.
            await Navigation.PushAsync(new StudentPage(student));
        }
    }
}

事件参数的SelectedItem属性是被轻击的Student对象,处理程序将其用作PushAsync调用中StudentPage类的参数。
另请注意,处理程序将ListView的SelectedItem属性设置为null。 这取消选择该项目,以便在用户返回SchoolPage和用户时仍然选择它
可以再次点击它。 但是将SelectedItem属性设置为null也会导致对ItemSelected事件处理程序的另一次调用。 幸运的是,如果SelectedItem为null,则处理程序会忽略该事件。
StudentPage的代码隐藏文件只是使用该构造函数参数来设置页面的Bind ingContext:

public partial class StudentPage : ContentPage
{
    public StudentPage(Student student)
    {
        InitializeComponent();
        BindingContext = student;
    }
}

StudentPage类的XAML文件包含对Student类的各种属性的绑定:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 x:Class="SchoolAndStudents.StudentPage"
 Title="Student">
    <StackLayout>
        <!-- Name -->
        <StackLayout Orientation="Horizontal"
 HorizontalOptions="Center"
Spacing="0">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style TargetType="Label">
                        <Setter Property="FontSize" Value="Large" />
                        <Setter Property="FontAttributes" Value="Bold" />
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>
            <Label Text="{Binding LastName}" />
            <Label Text="{Binding FirstName, StringFormat=', {0}'}" />
            <Label Text="{Binding MiddleName, StringFormat=' {0}'}" />
        </StackLayout>
        <!-- Photo -->
        <Image Source="{Binding PhotoFilename}"
 VerticalOptions="FillAndExpand" />
        <!-- Sex -->
        <Label Text="{Binding Sex, StringFormat='Sex = {0}'}"
 HorizontalOptions="Center" />
        <!-- GPA -->
        <Label Text="{Binding GradePointAverage, StringFormat='G.P.A. = {0:F2}'}"
 HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

XAML文件不需要按钮或任何其他用户界面对象返回到SchoolPage,因为它是作为平台的标准导航用户界面的一部分或作为手机本身的一部分自动提供的:
2019_04_23_100104
通过构造函数将信息传递到导航页面是通用的,但对于这个特定的示例,它是不必要的。 StudentPage可以有一个无参数构造函数,而SchoolPage可以在PushAsync调用中设置新创建的StudentPage的BindingContext:

await Navigation.PushAsync(new StudentPage { BindingContext = student });

任何一种方法的问题之一是在程序暂停时保留应用程序状态。 如果希望StudentPage在程序终止时保存当前学生,则需要保存Student对象的所有属性。 但是当程序再次启动时重新创建该Student对象时,它与Students集合中同一学生的特定Student对象不同,即使所有属性都相同。
如果已知学生集合是常量,则StudentPage更有意义的是仅将一个索引保存到引用此特定Student对象的Students集合中。 但在此示例中,StudentPage无权访问该索引或学生集合。

目录
相关文章
|
7月前
|
机器学习/深度学习 传感器 编解码
人机融合智能 | 脑机接口和脑机融合
脑机接口是一种在大脑与外部设备间建立直接信息交流的技术,能实现意念控制设备或对大脑进行调控。脑机融合则进一步将生物脑与机器智能结合,推动人机协同交互。本文介绍了脑机接口的技术框架、信号采集与解码方法,并探讨其在医疗康复、人机交互等领域的应用前景及挑战。
379 0
|
并行计算 数据可视化 数据处理
面向未来的数据科学工具链:Dask与Jupyter生态系统的融合
【8月更文第29天】随着数据量的不断增长,传统的数据处理方法已经难以满足科研和商业的需求。Dask 是一个并行计算库,能够有效地处理大规模数据集,同时它与 Jupyter Notebook 和其他数据科学工具的无缝集成,使得数据科学家能够构建更加高效的工作流程。本文将探讨如何利用 Dask 与 Jupyter 生态系统构建现代化的数据科学工作流,并通过具体的代码示例展示其实现过程。
283 1
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
742 5
|
JavaScript
Vue组件点击事件不触发的问题,添加事件修饰符native解决
Vue组件点击事件不触发的问题,添加事件修饰符native解决
1280 0
|
网络协议 Unix Linux
Linux 多种方式实现文件共享(三)NFS 6
【8月更文挑战第6天】NFS 即网络文件系统,是一种使用于分布式文件系统的协议,NFS 功能是通过网络让不同的机器,不同的操作系统能够彼此分享各自的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据
467 13
|
存储 运维 架构师
Netty API网关实操系列(二)
Netty API网关实操系列(二)
|
网络协议 数据安全/隐私保护 网络架构
深入理解OSI模型及其层次结构
【8月更文挑战第24天】
824 0
|
机器学习/深度学习
【阿旭机器学习实战】【21】通过SVM分类与回归实战案例,对比支持向量机(SVM)3种SVM不同核函数
【阿旭机器学习实战】【21】通过SVM分类与回归实战案例,对比支持向量机(SVM)3种SVM不同核函数
【阿旭机器学习实战】【21】通过SVM分类与回归实战案例,对比支持向量机(SVM)3种SVM不同核函数
ueditor1.5 百度富文本 编辑器增加字间距功能及按钮
ueditor1.5 百度富文本 编辑器增加字间距功能及按钮
366 0