导出 (0) 打印
全部展开

演练:访问 Windows Phone 的联系人和日历数据

2012/2/9

在本演练中,您生成一个简单的联系人和日历应用程序。在本演练中创建的应用程序显示联系人、约会以及提供数据的帐户。此应用程序的完整版本已可供下载。有关更多信息,请参阅 Windows Phone 的代码示例

注意注意:

Windows Phone SDK 7.1 为您提供对用户的联系人数据(跨用户的不同帐户聚合在一起)的只读访问。有关更多信息,请参阅 Windows Phone 的联系人和日历

在本演练中,您将执行下列任务。

  • 访问联系人和日历数据。

  • 将联系人、约会和帐户绑定到用户界面。

  • 显示各个联系人(包括照片)和约会的详细信息。

  • 通过创建一个自定义的数据转换器将联系人照片数据绑定到用户界面。

完整的应用程序如下所示。

完整的解决方案包含以下组件。

应用程序的主页应用程序的解决方案资源管理器

为了完成本演练,计算机上必须安装 Windows Phone SDK:有关更多信息,请参阅安装 Windows Phone SDK

首先,创建一个名为 ContactsAndCalendarTestApp 的 Windows Phone 新应用程序项目。在后面的步骤中,您将向您的应用程序中添加代码,假定该应用程序名称为 ContactsAndCalendarTestApp。如果要为应用程序选择不同的名称,则必须更改代码中的命名空间引用。

创建应用程序项目的步骤

  1. 在 Visual Studio 中的“文件”菜单中,指向“新建”,然后单击“项目”

    将显示“新建项目”对话框。

  2. 在左窗格中,单击“已安装模板”,展开“Visual C#”“Visual Basic”,然后单击“Silverlight for Windows Phone”

  3. 在项目类型列表中,单击“Windows Phone 应用程序”

  4. “名称”框中键入 ContactsAndCalendarTestApp

  5. 单击“确定”

    将显示“新建 Windows Phone 应用程序”对话框。

  6. “Windows Phone 目标版本”下拉列表中,选择“Windows Phone 7.1”,然后单击“确定”

    将创建新的应用程序项目并在 Visual Studio 中打开。

该应用程序包含一个主页,该主页具有三个 Pivot 项,这三项分别用于联系人、约会和帐户。还有两个用于联系人和约会详细信息的附加页面。

设置应用程序结构的步骤

  1. “解决方案资源管理器”中,选择 MainPage.xaml,然后按 Delete 键将其删除。

  2. “解决方案资源管理器”中,右键单击该项目,指向“添加”,然后单击“新项”

    将显示“添加新项”对话框。

  3. 选择“Windows Phone Pivot 页面”,输入名称 MainPage.xaml,然后单击“添加”

    将在设计器中打开新的 Pivot 页面。

  4. 在 XAML 代码中,找到名为 LayoutRoot 的 GRID 元素。将从此处到文件结尾的所有内容替换为以下代码。这将创建三个 Pivot 项,稍后您将填写这些项。

        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
    
            <!--Pivot Control-->
            <controls:Pivot Title="Contacts and Calendar Test App" >
    
                <!--Pivot item one-->
                <controls:PivotItem Header="contacts">
                </controls:PivotItem>
    
    
                <!--Pivot item two-->
                <controls:PivotItem Header="accounts">
                </controls:PivotItem>
    
    
                <!--Pivot item three-->
                <controls:PivotItem Header="appointments">
                </controls:PivotItem>
    
            </controls:Pivot>
        </Grid>
    </phone:PhoneApplicationPage>
    
  5. “解决方案资源管理器”中,右键单击该项目,指向“添加”,然后单击“新项”

    将显示“添加新项”对话框。

  6. 选择“Windows Phone 纵向页面”,输入名称 AppointmentDetails.xaml,然后单击“添加”

    将在设计器中打开新的页面。

  7. “解决方案资源管理器”中,右键单击该项目,指向“添加”,然后单击“新项”

    将显示“添加新项”对话框。

  8. 选择“Windows Phone 纵向页面”,输入名称 ContactDetails.xaml,然后单击“添加”

    将在设计器中打开新的页面。

  9. “解决方案资源管理器”中,右键单击“App.xaml”,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  10. 在该类的顶部,添加以下代码。该代码将创建两个全局静态变量,您可以使用这些变量在主页和详细信息页面之间传递数据。

    public static Microsoft.Phone.UserData.Contact con;
    public static Microsoft.Phone.UserData.Appointment appt;
    
  11. (可选)通过注释掉以下代码来禁用帧速率计数器。

    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    

在此过程中,您运行该应用程序以测试您的进度。

测试应用程序的步骤

  1. “文件”菜单上,单击“全部保存”。(Ctrl+Shift+S)

  2. “生成”(或 Visual Studio 2010 Express for Windows® Phone 7.1 中的“调试”菜单)上,单击“生成解决方案”。(Ctrl+Shift+B)

  3. 在标准工具栏上,将应用程序的部署目标设置为“Windows Phone 模拟器”“Windows Phone 设备”

    选择模拟器的标准工具栏上的目标选择设备的标准工具栏上的目标

  4. “调试”菜单上,单击“启动调试”。(F5)

    该应用程序启动并显示主页。

  5. 滑动 Pivot 项。应该显示所有三个 Pivot 项,标题分别为“联系人”“帐户”“约会”

  6. “调试”菜单上,单击“停止调试”。(F5)

访问联系人数据的过程是获取对 Contacts 对象的引用,通过调用 SearchAsync 对其执行异步搜索,然后在 SearchCompleted 事件处理程序中捕获 Contact 对象集合形式的结果。

创建联系人 Pivot 项用户界面的步骤

  1. “解决方案资源管理器”中,双击 MainPage.xaml 以在设计器中打开它。

  2. 找到第一个 Pivot 项并将其替换为以下代码。该代码将创建文本框、单选按钮以及用于搜索联系人的按钮。还创建包含搜索结果的列表框。

    <controls:PivotItem Header="contacts">
        <StackPanel Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
    
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
    
                <TextBox Grid.Row="0" Grid.ColumnSpan="2" Name="contactFilterString" />
                <RadioButton Grid.Row="1" Grid.Column="0" Checked="FilterChange" Name="name" Content="name" />
                <RadioButton Grid.Row="1" Grid.Column="1" Checked="FilterChange" Name="phone" Content="phone"/>
                <RadioButton Grid.Row="2" Grid.Column="0" Checked="FilterChange" Name="email" Content="email"/>
                <Button Grid.Row="2" Grid.Column="1" Content="search" Click="SearchContacts_Click" />
            </Grid>
    
            <TextBlock Name="ContactResultsLabel" Text="Search for contacts" TextWrapping="Wrap" Margin="12,0,0,0" />
    
            <ListBox Name="ContactResultsData" ItemsSource="{Binding}" Tap="ContactResultsData_Tap" Height="300" Margin="24,0,0,0" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Name="ContactResults" Text="{Binding Path=DisplayName, Mode=OneWay}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" Margin="18,8,0,0" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </controls:PivotItem>
    
    

访问联系人数据的步骤

  1. “解决方案资源管理器”中,右键单击 MainPage.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  2. 将该代码替换为以下内容。该代码将默认联系人搜索筛选器设置为 none,并将默认联系人搜索类型设置为 name。还包含选择单选按钮时更改搜索筛选器的代码。有关更多信息,请参阅 Windows Phone 的联系人筛选和匹配

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.UserData;
    
    namespace ContactsAndCalendarTestApp
    {
        public partial class MainPage : PhoneApplicationPage
        {
            FilterKind contactFilterKind = FilterKind.None;
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
    
                name.IsChecked = true;
            }
    
    
            private void FilterChange(object sender, RoutedEventArgs e)
            {
                String option = ((RadioButton)sender).Name;
    
                InputScope scope = new InputScope();
                InputScopeName scopeName = new InputScopeName();
    
                switch (option)
                {
                    case "name":
                        contactFilterKind = FilterKind.DisplayName;
                        scopeName.NameValue = InputScopeNameValue.Text;
                        break;
    
                    case "phone":
                        contactFilterKind = FilterKind.PhoneNumber;
                        scopeName.NameValue = InputScopeNameValue.TelephoneNumber;
                        break;
    
                    case "email":
                        contactFilterKind = FilterKind.EmailAddress;
                        scopeName.NameValue = InputScopeNameValue.EmailSmtpAddress;
                        break;
    
                    default:
                        contactFilterKind = FilterKind.None;
                        break;
                }
    
                scope.Names.Add(scopeName);
                contactFilterString.InputScope = scope;
                contactFilterString.Focus();
            }
        }//End page class
    }//End namespace
    
  3. 在构造函数之后,添加下面的代码。该代码包含搜索按钮单击事件,并启动异步联系人搜索。

    private void SearchContacts_Click(object sender, RoutedEventArgs e)
    {
        ContactResultsLabel.Text = "results are loading...";
        ContactResultsData.DataContext = null;
    
        Contacts cons = new Contacts();
    
        cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(Contacts_SearchCompleted);
    
        cons.SearchAsync(contactFilterString.Text, contactFilterKind, "Contacts Test #1");
    }
    
  4. 在单击事件之后,添加下面的代码。该代码包含处理异步搜索的已完成事件的方法。该代码通过将列表框的数据上下文设置为等于搜索结果,将联系人数据绑定到用户界面。如果没有结果,则该代码包含错误处理。该代码还根据是否有结果更改列表框标签的文本。

    void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
    {
        //MessageBox.Show(e.State.ToString());
    
        try
        {
            //Bind the results to the list box that displays them in the UI
            ContactResultsData.DataContext = e.Results;
        }
        catch (System.Exception)
        {
            //That's okay, no results
        }
    
        if (ContactResultsData.Items.Count > 0)
        {
            ContactResultsLabel.Text = "results (tap name for details...)";
        }
        else
        {
            ContactResultsLabel.Text = "no results";
        }
    }
    
  5. 在搜索已完成事件之后,添加下面的代码。当您点按结果列表中的某个联系人时,该代码将该联系人存储在某个全局变量中,然后导航到该联系人详细信息页面。

    private void ContactResultsData_Tap(object sender, GestureEventArgs e)
    {
        App.con = ((sender as ListBox).SelectedValue as Contact);
    
        NavigationService.Navigate(new Uri("/ContactDetails.xaml", UriKind.Relative));
    }
    

在主页上点按结果列表中的某个联系人时,应用程序将导航到该联系人详细信息页面。

显示联系人详细信息的步骤

  1. “解决方案资源管理器”中,双击 ContactDetails.xaml 以在设计器中打开它。

  2. 找到名为 LayoutRoot 的 GRID 元素。将从此处到文件结尾的所有内容替换为以下代码。这将为联系人的名称创建一个文本框,为联系人的照片创建一个图像,并且创建包含其他联系人数据的列表框。

        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,0">
                <TextBlock x:Name="ApplicationTitle" Text="Contacts and Calendar Test App" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="contact details" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - place additional content here-->
            <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    
                <TextBlock Text="{Binding Path=DisplayName, Mode=OneWay}" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" />
    
                <Border BorderThickness="2" HorizontalAlignment="Left" BorderBrush="{StaticResource PhoneAccentBrush}" >
                    <Image Name="Picture" Height="85" Width="85" HorizontalAlignment="Left" />
                </Border>
    
                <TextBlock Text="phone numbers" Margin="12,12,0,0"/>
                <ListBox ItemsSource="{Binding Path=PhoneNumbers}" Height="60"  Margin="36,0,0,0">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Path=Kind, Mode=OneWay}" />
                                <TextBlock Grid.Column="1" Text=":  " />
                                <TextBlock Grid.Column="2" Text="{Binding Path=PhoneNumber, Mode=OneWay}" />
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
    
                <TextBlock Text="email addresses" Margin="12,12,0,0" />
                <ListBox ItemsSource="{Binding Path=EmailAddresses}" Height="60"  Margin="36,0,0,0">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Path=Kind, Mode=OneWay}" />
                                <TextBlock Grid.Column="1" Text=":  " />
                                <TextBlock Grid.Column="2" Text="{Binding Path=EmailAddress, Mode=OneWay}" />
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
    
                <TextBlock Text="web sites" Margin="12,12,0,0" />
                <ListBox ItemsSource="{Binding Path=Websites}" Height="60"  Margin="36,0,0,0" />
    
                <TextBlock Text="company information" Margin="12,12,0,0" />
                <ListBox ItemsSource="{Binding Path=Companies}" Height="60"  Margin="36,0,0,0">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Path=CompanyName, Mode=OneWay}" />
                                <TextBlock Grid.Column="1" Text=":  " />
                                <TextBlock Grid.Column="2" Text="{Binding Path=JobTitle, Mode=OneWay}" />
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
    
                <TextBlock Text="accounts" Margin="12,12,0,0" />
                <ListBox ItemsSource="{Binding Path=Accounts}" Height="60" Margin="36,0,0,0">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding Path=Kind, Mode=OneWay}" />
                                <TextBlock Grid.Column="1" Text=":  " />
                                <TextBlock Grid.Column="2" Text="{Binding Path=Name, Mode=OneWay}" />
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </phone:PhoneApplicationPage>
    
    
  3. “解决方案资源管理器”,右键单击 ContactDetails.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  4. 将该代码替换为以下内容。该代码将页面的数据上下文设置为在主页上选择的联系人。还调用 GetPicture 方法并将结果显示在图像控件中。

    using System;
    using Microsoft.Phone.Controls;
    using System.Windows.Media.Imaging;
    
    namespace ContactsAndCalendarTestApp
    {
        public partial class ContactDetails : PhoneApplicationPage
        {
            public ContactDetails()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
    
                //Set the data context for this page to the selected contact
                this.DataContext = App.con;
    
                try
                {
                    //Try to get a picture of the contact
                    BitmapImage img = new BitmapImage();
                    img.SetSource(App.con.GetPicture());
                    Picture.Source = img;
                }
                catch (Exception)
                {
                    //can't get a picture of the contact
                }
            }
        }
    }
    

在此过程中,您运行该应用程序以测试您的进度。

注意注意:

Windows Phone 模拟器包含示例联系人。可以使用 Windows Phone 模拟器或物理设备测试此过程。但是,示例联系人没有照片。

测试应用程序的步骤

  1. 在模拟器或设备上启动您的应用程序。如有必要,使用第一个检查点中的说明。

    该应用程序启动并显示主页。

  2. 在文本框中,输入字母 A,然后单击“搜索”

    结果将填充列表。如果在 Windows Phone 模拟器上测试应用程序,则会看到以下内容。

    Andrew Hill

    Arturo Lopez

  3. 点按结果列表中的某个姓名。

    将打开该联系人的详细信息页面并显示该联系人的详细信息。并非所有联系人的所有数据都可用。

  4. “调试”菜单上,单击“停止调试”。(F5)

访问日历数据的过程是获取对 Appointments 对象的引用,通过调用 SearchAsync 对其执行异步搜索,然后在 SearchCompleted 事件处理程序中捕获 Appointment 对象集合形式的结果。

创建约会 Pivot 项用户界面的步骤

  1. “解决方案资源管理器”中,双击 MainPage.xaml 以在设计器中打开它。

  2. 找到第三个 Pivot 项并将其替换为以下代码。该代码将为开始和结束日期创建标签、搜索按钮以及包含搜素结果的列表框。

    <controls:PivotItem Header="appointments">
        <StackPanel Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
    
            <TextBlock Text="appointments between" Foreground="{StaticResource PhoneAccentBrush}" />
    
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
    
                <TextBlock Grid.Row="0" Grid.Column="0" Text="start date" />
                <TextBlock Grid.Row="0" Grid.Column="1" Text="end date" />
                <TextBlock Grid.Row="1" Grid.Column="0" Text="placeholder" Name="StartDate" />
                <TextBlock Grid.Row="1" Grid.Column="1" Text="placeholder" Name="EndDate" />
                <Button Grid.Row="2" Grid.ColumnSpan="2" Content="search" Click="SearchAppointments_Click" HorizontalAlignment="Center" />
            </Grid>
    
            <TextBlock Name="AppointmentResultsLabel" Text="search for appointments" TextWrapping="Wrap" />
    
            <ListBox Name="AppointmentResultsData" ItemsSource="{Binding}" Tap="AppointmentResultsData_Tap" Height="400"  ScrollViewer.ManipulationMode="Control" Margin="24,0,0,0" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Subject, Mode=OneWay}"  FontSize="{StaticResource PhoneFontSizeExtraLarge}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </controls:PivotItem>
    

访问约会数据的步骤

  1. “解决方案资源管理器”中,右键单击 MainPage.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  2. MainPage 类的构造函数后面添加以下代码。该代码包含搜索按钮单击事件,并启动异步约会搜索。该代码将搜索未来一周内的约会。

    private void SearchAppointments_Click(object sender, RoutedEventArgs e)
    {
        AppointmentResultsLabel.Text = "results are loading...";
        AppointmentResultsData.DataContext = null;
        Appointments appts = new Appointments();
    
        appts.SearchCompleted += new EventHandler<AppointmentsSearchEventArgs>(Appointments_SearchCompleted);
    
        DateTime start = DateTime.Now;
        DateTime end = start.AddDays(7);
    
        appts.SearchAsync(start, end, 20, "Appointments Test #1");
    }
    
  3. 在单击事件之后,添加下面的代码。该代码包含处理异步搜索的已完成事件的方法。该代码通过将列表框的数据上下文设置为等于搜索结果,将约会数据绑定到用户界面。如果没有结果,则该代码包含错误处理。该代码还根据是否有结果更改列表框标签的文本。

    void Appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
    {
        StartDate.Text = e.StartTimeInclusive.ToShortDateString();
        EndDate.Text = e.EndTimeInclusive.ToShortDateString();
    
        try
        {
            //Bind the results to the list box that displays them in the UI
            AppointmentResultsData.DataContext = e.Results;
        }
        catch (System.Exception)
        {
            //That's okay, no results
        }
    
        if (AppointmentResultsData.Items.Count > 0)
        {
            AppointmentResultsLabel.Text = "results (tap for details...)";
        }
        else
        {
            AppointmentResultsLabel.Text = "no results";
        }
    }
    
    
  4. 在搜索已完成事件之后,添加下面的代码。当您点按结果列表中的某个约会时,该代码将该约会存储在某个全局变量中,然后导航到该约会详细信息页面。

    private void AppointmentResultsData_Tap(object sender, GestureEventArgs e)
    {
        App.appt = ((sender as ListBox).SelectedValue as Appointment);
    
        NavigationService.Navigate(new Uri("/AppointmentDetails.xaml", UriKind.Relative));
    }
    

在主页上点按结果列表中的某个约会时,应用程序将导航到该约会详细信息页面。

显示约会详细信息的步骤

  1. “解决方案资源管理器”中,双击 AppointmentDetails.xaml 以在设计器中打开它。

  2. 找到名为 LayoutRoot 的 GRID 元素。将从此处到文件结尾的所有内容替换为以下代码。该代码为约会主题创建一个文本框并创建一个包含其他约会数据的滚动查看器。

        <phone:PhoneApplicationPage.Resources>
    
            <DataTemplate x:Key="AttendeeTemplate">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" Text="{Binding Path=DisplayName, Mode=OneWay}" TextWrapping="Wrap" />
                    <TextBlock Grid.Column="1" Text=":  " />
                    <TextBlock Grid.Column="2" Text="{Binding Path=EmailAddress, Mode=OneWay}" TextWrapping="Wrap" />
                </Grid>
            </DataTemplate>
        </phone:PhoneApplicationPage.Resources>
    
    
        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,6">
                <TextBlock x:Name="ApplicationTitle" Text="Contacts and Calendar Test App" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="appt details" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <TextBlock Grid.Row="1" Text="{Binding Path=Subject, Mode=OneWay}" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" TextWrapping="Wrap" />
    
            <!--ContentPanel - place additional content here-->
            <ScrollViewer x:Name="ContentPanel" Grid.Row="2" Margin="12,0,12,0">
                <StackPanel>
    
                    <TextBlock Text="{Binding Path=Details, Mode=OneWay}"  Margin="12,0,0,0" TextWrapping="Wrap" />
                    
                    <TextBlock Text="{Binding Path=StartTime, Mode=OneWay}"  Margin="12,12,0,0"/>
                    <TextBlock Text="{Binding Path=EndTime, Mode=OneWay}"  Margin="12,0,0,0"/>
    
                    <TextBlock Text="{Binding Path=Location, Mode=OneWay}"  Margin="12,12,0,0"/>
    
                    <TextBlock Text="{Binding Path=Status, Mode=OneWay}"  Margin="12,12,0,0"/>
    
                    <TextBlock Text="organizer" Margin="12,12,0,0" />
                    <ListBox ItemsSource="{Binding Path=Organizer}" ItemTemplate="{StaticResource AttendeeTemplate}" Margin="24,0,0,0" />
    
                    <TextBlock Text="attendees" Margin="12,12,0,0" />
                    <ListBox ItemsSource="{Binding Path=Attendees}" ItemTemplate="{StaticResource AttendeeTemplate}" Margin="24,0,0,0" />
    
                    <TextBlock Text="accounts" Margin="12,12,0,0" />
                    <ListBox ItemsSource="{Binding Path=Accounts}" Margin="24,0,0,0">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0" Text="{Binding Path=Kind, Mode=OneWay}" />
                                    <TextBlock Grid.Column="1" Text=":  " />
                                    <TextBlock Grid.Column="2" Text="{Binding Path=Name, Mode=OneWay}" />
                                </Grid>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </phone:PhoneApplicationPage>
    
  3. “解决方案资源管理器”,右键单击 AppointmentDetails.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  4. 将该代码替换为以下内容。该代码将页面的数据上下文设置为在主页上选择的约会。

    using Microsoft.Phone.Controls;
    
    namespace ContactsAndCalendarTestApp
    {
        public partial class AppointmentDetails : PhoneApplicationPage
        {
            public AppointmentDetails()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
    
                //Set the data context for this page to the selected appointment
                this.DataContext = App.appt;
            }
        }
    }
    
    

在此过程中,您运行该应用程序以测试您的进度。

重要说明重要说明:

Windows Phone 模拟器不包含示例约会。您可以使用 Windows Phone 模拟器测试此过程,但您只能在物理设备上查看约会。

测试应用程序的步骤

  1. 在模拟器或设备上启动您的应用程序。如有必要,使用第一个检查点中的说明。

    该应用程序启动并显示主页。

  2. 滑动到“约会” Pivot 姓名,然后单击“搜索”按钮。

    结果将填充列表。

  3. 点按列表中的某个约会。

    将打开该约会的详细信息页面并显示该约会的详细信息。如果详细信息较长,则滚动该页面以查看所有详细信息。

  4. “调试”菜单上,单击“停止调试”。(F5)

Windows Phone 提供跨用户不同帐户的用户联系人数据的聚合视图。信息可以来自诸如在手机自身中输入的数据、社交网络站点或其他数据服务提供商之类的源。在此过程中,您显示提供联系人和日历数据的帐户。

访问帐户数据的步骤

  1. “解决方案资源管理器”中,双击 MainPage.xaml 以在设计器中打开它。

  2. 找到第二个 Pivot 项并将其替换为以下代码。该代码将创建两个列表框,一个用于联系人帐户,一个用于约会帐户。该代码还使用一个您将在下一步添加的项模板。

    <controls:PivotItem Header="accounts">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
    
            <StackPanel Grid.Row="0" >
    
                <TextBlock Text="contact accounts" Foreground="{StaticResource PhoneAccentBrush}" Style="{StaticResource PhoneTextLargeStyle}" />
                <ListBox Name="ContactAccounts" ItemsSource="{Binding}" ItemTemplate="{StaticResource AccountTemplate}" Height="200" Margin="24,0,0,0" />
            </StackPanel>
    
            <StackPanel Grid.Row="1" >
    
                <TextBlock Text="appointment accounts" Foreground="{StaticResource PhoneAccentBrush}" Style="{StaticResource PhoneTextLargeStyle}" />
                <ListBox Name="CalendarAccounts" ItemsSource="{Binding}" ItemTemplate="{StaticResource AccountTemplate}" Height="200" Margin="24,0,0,0" />
            </StackPanel>
        </Grid>
    </controls:PivotItem>
    
  3. PHONE:PHONEAPPLICATIONPAGE 元素之后、GRID 元素之前,添加以下代码。该模板将列表中每个条目的帐户名称和帐户类型显示在一行上。

    <phone:PhoneApplicationPage.Resources>
    
        <DataTemplate x:Key="AccountTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Path=Name, Mode=OneWay}" />
                <TextBlock Grid.Column="1" Text=" account: " />
                <TextBlock Grid.Column="2" Text="{Binding Path=Kind, Mode=OneWay}" />
            </Grid>
        </DataTemplate>
    
    </phone:PhoneApplicationPage.Resources>
    
  4. “解决方案资源管理器”中,右键单击 MainPage.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  5. 在构造函数中,任何现有代码之后,添加以下代码。该代码通过将联系人列表框的数据上下文设置为 Accounts 属性并将约会列表框设置为 Accounts 属性,将帐户数据绑定到用户界面。

    ContactAccounts.DataContext = (new Contacts()).Accounts;
    CalendarAccounts.DataContext = (new Appointments()).Accounts;
    

在此过程中,您运行该应用程序以测试您的进度。

测试应用程序的步骤

  1. 在模拟器或设备上启动您的应用程序。如有必要,使用第一个检查点中的说明。

    该应用程序启动并显示主页。

  2. 滑动到帐户 Pivot 项。

    结果将填充列表。如果在 Windows Phone 模拟器上测试应用程序,则会在列表中看到以下内容。

    Phone account: Phone

  3. “调试”菜单上,单击“停止调试”。(F5)

在上面的过程中,您在联系人详细信息页面上显示了单个联系人的照片。在此过程中,您将多个联系人照片数据直接绑定到主页上的结果列表。由于联系人照片不是属性(联系人照片通过调用 GetPicture 方法返回),因此必须在数据绑定它们之前创建一个自定义的数据转换器。

将联系人照片数据绑定到用户界面的步骤

  1. “解决方案资源管理器”中,右键单击 MainPage.xaml,然后单击“查看代码”

    代码隐藏文件将在代码编辑器中打开。

  2. 找到以下代码。在下一步中,您将在该行之后添加新代码。

    }//End page class
    
  3. MainPage 类代码之后,添加以下新类。这是自定义数据转换器。

    public class ContactPictureConverter : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Contact c = value as Contact;
            if (c == null) return null;
    
            System.IO.Stream imageStream = c.GetPicture();
            if (null != imageStream)
            {
                return Microsoft.Phone.PictureDecoder.DecodeJpeg(imageStream);
            }
            return null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }//End converter class
    
  4. “解决方案资源管理器”中,双击 MainPage.xaml 以在设计器中打开它。

  5. <phone:PhoneApplicationPage> 标记中,借助其他命名空间声明,添加以下代码。该代码允许您访问自定义数据转换器。

    xmlns:MyApp="clr-namespace:ContactsAndCalendarTestApp"
    
  6. 找到您在上面过程中添加的 PHONE:PHONEAPPLICATION.RESOURCES 元素。在数据模板之后,</phone:PhoneApplicationPage.Resources> 标记之前,添加以下代码。

    <MyApp:ContactPictureConverter x:Key="ContactPictureConverter" />
    
  7. 在第一个 Pivot 项的联系人结果中,找到以下数据模板。

    <DataTemplate>
        <TextBlock Name="ContactResults" Text="{Binding Path=DisplayName, Mode=OneWay}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" Margin="18,8,0,0" />
    </DataTemplate>
    
  8. 将现有数据模板替换以下内容。这将添加联系人的照片,并使用自定义数据转换器进行数据绑定。

    <DataTemplate>
        <StackPanel Orientation="Horizontal" >
            <Border BorderThickness="2" HorizontalAlignment="Left" VerticalAlignment="Center" BorderBrush="{StaticResource PhoneAccentBrush}" >
                <Image Source="{Binding Converter={StaticResource ContactPictureConverter}}" Width="48" Height="48" Stretch="Fill"  />
            </Border>
            <TextBlock Name="ContactResults" Text="{Binding Path=DisplayName, Mode=OneWay}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" Margin="18,8,0,0" />
        </StackPanel>
    </DataTemplate>
    

在此过程中,您运行该应用程序以测试您的进度。

注意注意:

Windows Phone 模拟器包含示例联系人。可以使用 Windows Phone 模拟器或物理设备测试此过程。但是,示例联系人没有照片。

测试应用程序的步骤

  1. 在模拟器或设备上启动您的应用程序。如有必要,使用第一个检查点中的说明。

    该应用程序启动并显示主页。

  2. 在文本框中,输入字母 A,然后单击“搜索”

    结果将填充列表。如果在物理设备上测试应用程序,则某些联系人可能有照片。滚动该列表,直到您看到有照片的联系人。

  3. “调试”菜单上,单击“停止调试”。(F5)

您可以采用以下方式展开应用程序的功能。

  • 更改约会搜索以从用户获取开始和结束日期。

  • 更改联系人详细信息页面以使用滚动查看器,它类似于约会详细信息页面。

  • 更改联系人搜索结果以显示联系人的姓名、电子邮件或电话号码(取决于用户执行的搜索类型)。

  • 添加搜索固定到“开始”屏幕的所有联系人的功能。有关更多信息,请参阅 Windows Phone 的联系人筛选和匹配

显示:
© 2014 Microsoft