图解使用Win8Api进行Metro风格的程序开发十一----联系人选择

我们紧接着上篇,这篇将介绍如何使用Windows.ApplicationModel.Contacts API
中的ContactPicker来选择联系人,使用ContactPicker的PickSingleContactAsync方法
来选择单个联系人,使用ContactPicker的PickMultipleContactsAsync来选择多个联系人
-----------------------------------我是华丽的分割线-----------------------------------------
我们紧接着上篇,这篇将使用Windows.ApplicationModel.Contacts API
中的ContactPicker来选择联系人,使用ContactPicker的PickSingleContactAsync方法
来选择单个联系人,使用ContactPicker的PickMultipleContactsAsync来选择多个联系人

本篇将介绍如下3个方面:
  a)制作选择联系人页面
  b)选择单个联系人
  c)选择多个联系人

我们的创建的步骤如下:
1)为了组织文件方便,我们先建一个文件夹ContactPicker
2)向文件夹中添加如下文件:
 ContactPickerPage.xaml,SinglePicker.xaml,MultiplePicker.xaml
 创建方法请参照前一篇.
3)此时的解决方案结构如下:

 

4)向我们的DataSource添加导航所需要的信息
  修改我们的SampleDataSource.cs文件中的SampleDataSource类中的代码,
  代码如下: 

View Code
        public SampleDataSource()
        {
            #region Group1
            var group1 = new SampleDataGroup("FilePicker",
              "Use Windows.Storage.Pickers API",
              "Access and save files using the file picker",
              "Assets/FilePicker.jpg",
              "");
            group1.Items.Add(new SampleDataItem("FilePicker-PickASinglePhoto",
                    "Pick a single photo",
                    "only one file can selected,file type is jpg,jpeg,png",
                    "Assets/FilePicker.jpg",
                    "only one file can selected ",
                    "",
                    group1,
                    typeof(PickASinglePhoto)));
            group1.Items.Add(new SampleDataItem("FilePicker-PickMultipleFiles",
                    "Pick multiple files",
                    "you can pick multiple files",
                    "Assets/FilePicker.jpg",
                    "pick multiple files",
                    "",
                    group1,
                    typeof(PickMultipleFiles)));
            group1.Items.Add(new SampleDataItem("FilePicker-PickAFolder",
                    "Pick a folder",
                    "you can pick a folder",
                    "Assets/FilePicker.jpg",
                    "Pick a folder",
                    "",
                    group1,
                    typeof(PickAFolder)));
            group1.Items.Add(new SampleDataItem("FilePicker-SaveAFile",
                    "Save a file",
                    "you can save a file",
                    "Assets/FilePicker.jpg",
                    "Save a file",
                    "",
                    group1,
                    typeof(SaveAFile)));
            this.AllGroups.Add(group1);
            #endregion

            #region Group2
            var group2 = new SampleDataGroup("FileAceess",
           "Using Windows.Storage API",
           "File access",
           "Assets/FileAccess.jpg",
           "");
            group2.Items.Add(new SampleDataItem("FileAceess-CreatingAFile",
                    "Create a file",
                    "Using CreateFileAsync Create a file",
                    "Assets/FileAccess.jpg",
                    "Using CreateFileAsync",
                    "",
                    group2,
                    typeof(CreatingAFile)));

            group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingText",
               "Write And Read A Text",
               "Using WriteTextAsync,ReadTextAsync Write And Read  Text",
               "Assets/FileAccess.jpg",
               "Using WriteTextAsync,ReadTextAsync",
               "",
               group2,
               typeof(WritingAndReadingText)));

            group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingBytes",
              "Writing and reading bytes in a file",
              "Using WriteBufferAsync,ReadBufferAsync Write And Read bytes",
              "Assets/FileAccess.jpg",
              "Using WriteBufferAsync,ReadBufferAsync",
              "",
              group2,
              typeof(WritingAndReadingBytes)));

            group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingUsingStream",
                "Writing and reading using a stream",
                "Using OpenAsync Writing and reading using a stream",
                "Assets/FileAccess.jpg",
                "Using OpenAsync",
                "",
                group2,
                typeof(WritingAndReadingUsingStream)));

            group2.Items.Add(new SampleDataItem("FileAceess-DisplayingFileProperties",
                "Displaying file properties",
                "Using GetBasicPropertiesAsync  Get File Properties",
                "Assets/FileAccess.jpg",
                "Using GetBasicPropertiesAsync",
                "",
                group2,
                typeof(DisplayingFileProperties)));

            group2.Items.Add(new SampleDataItem("FileAceess-PersistingAccess",
                "Persisting access to a storage item for future use",
                "Using MostRecentlyUsedList",
                "Assets/FileAccess.jpg",
                "Using MostRecentlyUsedList",
                "",
                group2,
                typeof(PersistingAccess)));

            group2.Items.Add(new SampleDataItem("FileAceess-CopyAFile",
                "Copy a file",
                "Using CopyAsync Copy a file",
                "Assets/FileAccess.jpg",
                "Using CopyAsync",
                "",
                group2,
                typeof(CopyAFile)));

            group2.Items.Add(new SampleDataItem("FileAceess-DeleteAFile",
                "Delete a file",
                "Using DeleteAsync Delete a file",
                "Assets/FileAccess.jpg",
                "Using DeleteAsync",
                "",
                group2,
                typeof(DeleteAFile)));

            this.AllGroups.Add(group2);
            #endregion

            #region Group3
            var group3 = new SampleDataGroup("AccountPictureName",
              "Use Windows.System.UserProfile API",
              "Account Picture Name",
              "Assets/AccountPictureName.jpg",
              "");
            group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserDisplayName",
                    "Get User DisplayName",
                    "Use UserInformation.GetDisplayNameAsync Get User DisplayName",
                    "Assets/AccountPictureName.jpg",
                    "Use UserInformation.GetDisplayNameAsync",
                    "",
                    group3,
                    typeof(GetUserDisplayName)));
            group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserFirstLastName",
                    "Get First Last Name",
                    "Use UserInformation.GetFirstNameAsync,GetLastNameAsync Get First Name",
                    "Assets/AccountPictureName.jpg",
                    "Use UserInformation.GetFirstNameAsync ",
                    "",
                    group3,
                    typeof(GetUserFirstLastName)));
            group3.Items.Add(new SampleDataItem("AccountPictureName-GetAccountPicture",
                    "Get Account Picture",
                    "Use UserInformation.GetAccountPicture Get Account Picture",
                    "Assets/AccountPictureName.jpg",
                    "Use UserInformation.GetAccountPicture",
                    "",
                    group3,
                    typeof(GetAccountPicture)));
            group3.Items.Add(new SampleDataItem("AccountPictureName-SetAccountPictureAndListen",
                    "Set AccountPicture And Listen",
                    "Use UserInformation.SetAccountPicturesAsync Set AccountPicture",
                    "Assets/AccountPictureName.jpg",
                    "Use UserInformation.SetAccountPicturesAsync",
                    "",
                    group3,
                    typeof(SetAccountPictureAndListen)));
            this.AllGroups.Add(group3);
            #endregion

            #region Group4
            var group4 = new SampleDataGroup("ApplicationSettings",
              "ApplicationSettings",
              " Use the Windows.UI.ApplicationSettings namespace and WinJS.UI.SettingsFlyout",
              "Assets/ApplicationSettings.jpg",
              "");
            group4.Items.Add(new SampleDataItem("ApplicationSettings-Default",
                    "Default behavior with no settings integration",
                    "Default behavior ",
                    "Assets/ApplicationSettings.jpg",
                    "Default behavior with no settings integration",
                    "",
                    group4,
                    typeof(Default)));
            group4.Items.Add(new SampleDataItem("ApplicationSettings-AddSettings",
                    "Add settings commands to the settings charm",
                    "Add settings",
                    "Assets/ApplicationSettings.jpg",
                    "Add settings commands to the settings charm ",
                    "",
                    group4,
                    typeof(AddSettings)));

            this.AllGroups.Add(group4);
            #endregion

            #region Group5
            var Group5 = new SampleDataGroup("AssociationLaunching",
              "Use Windows.System.Launcher API",
              "Association Launching",
              "Assets/AssociationLaunching.jpg",
              "");
            Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchFile",
                    "Launching a file",
                    "Use Windows.System.Launcher.LaunchFileAsync",
                    "Assets/AssociationLaunching.jpg",
                    "Use Windows.System.Launcher.LaunchFileAsync",
                    "",
                    Group5,
                    typeof(LaunchFile)));
            Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchUri",
                    "Launching a URI",
                    "Use Windows.System.Launcher.LaunchUriAsync",
                    "Assets/AssociationLaunching.jpg",
                    "Use Windows.System.Launcher.LaunchUriAsync",
                    "",
                    Group5,
                    typeof(LaunchUri)));
            Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveFile",
                    "Receiving a file",
                    "Receiving a file",
                    "Assets/AssociationLaunching.jpg",
                    "Receiving a file",
                    "",
                    Group5,
                    typeof(ReceiveFile)));
            Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveUri",
                    "Receiving a URI",
                    "Receiving a URI",
                    "Assets/AssociationLaunching.jpg",
                    "Receiving a URI",
                    "",
                    Group5,
                    typeof(ReceiveUri)));
            this.AllGroups.Add(Group5);
            #endregion

            #region Group6
            var Group6 = new SampleDataGroup("BackgroundTransfer",
              "Use Windows.Networking.BackgroundTransfer API",
              "BackgroundDownloader And BackgroundUploader",
              "Assets/BackgroundTransfer.jpg",
              "");
            Group6.Items.Add(new SampleDataItem("BackgroundTransfer-DownloadFile",
                    "Download Files",
                    "Use BackgroundDownloader",
                    "Assets/BackgroundTransfer.jpg",
                    "BackgroundDownloader",
                    "",
                    Group6,
                    typeof(DownloadFile)));
            Group6.Items.Add(new SampleDataItem("BackgroundTransfer-UploadFile",
                    "Upload Files",
                    "Use BackgroundUploader",
                    "Assets/BackgroundTransfer.jpg",
                    "BackgroundUploader",
                    "",
                    Group6,
                    typeof(UploadFile)));

            this.AllGroups.Add(Group6);
            #endregion

            #region Group7
            var Group7 = new SampleDataGroup("Clipboard",
              "Use Windows.ApplicationModel.DataTransfer API",
              "ClipboardOperation",
              "Assets/Clipboard.jpg",
              "");
            Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteText",
                    "Copy and paste text",
                    "Use Clipboard.GetContent,Clipboard.SetContent",
                    "Assets/Clipboard.jpg",
                    "Clipboard.GetContent,Clipboard.SetContent",
                    "",
                    Group7,
                    typeof(CopyAndPasteText)));
            Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteImage",
                    "Copy and paste an image",
                    "Use Clipboard.GetContent,Clipboard.SetContent",
                    "Assets/Clipboard.jpg",
                    "Clipboard.GetContent,Clipboard.SetContent",
                    "",
                    Group7,
                    typeof(CopyAndPasteImage)));
            Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteFile",
                    "Copy and paste files",
                    "Use Clipboard.GetContent,Clipboard.SetContent",
                    "Assets/Clipboard.jpg",
                    "Clipboard.GetContent,Clipboard.SetContent",
                    "",
                    Group7,
                    typeof(CopyAndPasteFile)));
            Group7.Items.Add(new SampleDataItem("Clipboard-OtherClipboardOperation",
                    "Other Clipboard operations",
                    "Use Clipboard.GetContent,Clipboard.SetContent",
                    "Assets/Clipboard.jpg",
                    "Clipboard.GetContent,Clipboard.SetContent",
                    "",
                    Group7,
                    typeof(OtherClipboardOperation)));

            this.AllGroups.Add(Group7);
            #endregion

            #region Group8
            var Group8 = new SampleDataGroup("Compression",
              "Use Windows.Storage.Compression API",
              "Compression And Decompression",
              "Assets/Compression.jpg",
              "");
            Group8.Items.Add(new SampleDataItem("Compression-CompressionAndDecompression",
                    "Compression And Decompression",
                    "Use Windows.Storage.Compression API",
                    "Assets/Compression.jpg",
                    "Compression And Decompression",
                    "",
                    Group8,
                    typeof(CompressionAndDecompression)));

            this.AllGroups.Add(Group8);
            #endregion

            #region Group9
            var Group9 = new SampleDataGroup("MediaButtons",
              "Use Windows.Media API",
              "Media Buttons",
              "Assets/MediaButtons.jpg",
              "");
            Group9.Items.Add(new SampleDataItem("MediaButtons-MediaEvents",
                    "Media Events",
                    "Use Windows.Media API",
                    "Assets/MediaButtons.jpg",
                    "Listening to hardware media transport events",
                    "",
                    Group9,
                    typeof(MediaEvents)));

            this.AllGroups.Add(Group9);
            #endregion

            #region Group10
            var Group10 = new SampleDataGroup("ContactPicker",
              "Use Windows.ApplicationModel.Contacts API",
              "Contact Picker",
              "Assets/ContactPicker.jpg",
              "");
            Group10.Items.Add(new SampleDataItem("ContactPicker-SinglePicker",
                    "Pick a single contact",
                    "Use ContactPicker.PickSingleContactAsync()",
                    "Assets/ContactPicker.jpg",
                    "PickSingleContactAsync",
                    "",
                    Group10,
                    typeof(SinglePicker)));
            Group10.Items.Add(new SampleDataItem("ContactPicker-MultiplePicker",
                    "Pick multiple contacts",
                    "Use ContactPicker.PickMultipleContactsAsync()",
                    "Assets/ContactPicker.jpg",
                    "PickMultipleContactsAsync",
                    "",
                    Group10,
                    typeof(MultiplePicker)));

            this.AllGroups.Add(Group10);
            #endregion
        }

5)我们的导航这样就做好了,效果图:

  点击 ContactPicker

6)由于我们需要对联系人进行绑定,先建一个联系人类RefactorContact: 

View Code
   public class RefactorContact
    {
        public string Id { get; private set; }
        public string Name { get; set; }
        public string HomeEmail { get; set; }
        public string WorkEmail { get; set; }
        public string HomePhone { get; set; }
        public string WorkPhone { get; set; }
        public string MobilePhone { get; set; }

        public string Address { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }

        public RefactorContact()
        {
            Id = Guid.NewGuid().ToString();
        }
    }

7)新建一个ContactPickerPage分布类:

View Code
    public sealed partial class ContactPickerPage : Page
    {
        ContactPickerUI contactPickerUI;

        public void Activate(ContactPickerActivatedEventArgs args)
        {
            contactPickerUI = args.ContactPickerUI;
            Window.Current.Content = this;
            this.OnNavigatedTo(null);
            Window.Current.Activate();
        }

        // Example contacts to pick from
        List<RefactorContact> contactSet = new List<RefactorContact>()
        {
            new RefactorContact()
            {
                Name = "Refactor",
                HomeEmail = "295240648@163.com",
                WorkEmail = "clhu@dcjet.com.cn",
                HomePhone = "3123123214214214",
                Address = "",
                Street = "",
                City = "",
                State = "",
                ZipCode = ""
            },
            new RefactorContact()
            {
                 Name = "Refactor1",
                HomeEmail = "295240648@163.com",
                WorkEmail = "clhu@dcjet.com.cn",
                HomePhone = "3123123214214214"
            },
            new RefactorContact()
            {
                Name = "Refactor2",
                HomeEmail = "295240648@163.com",
                WorkEmail = "clhu@dcjet.com.cn",
                HomePhone = "3123123214214214",
                ZipCode = "12345"
            },
            new RefactorContact()
            {
                Name = "Refactor3",
                HomeEmail = "295240648@163.com",
                WorkEmail = "clhu@dcjet.com.cn",
                HomePhone = "3123123214214214"
            },
            new RefactorContact()
            {
               Name = "Refactor4",
                HomeEmail = "295240648@163.com",
                WorkEmail = "clhu@dcjet.com.cn",
                HomePhone = "3123123214214214",
                ZipCode = "95111"
            }
        };
    }

8)修改我们的联系人选择页面:

  修改ContactPickerPage.xaml的xaml:

View Code
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                Click the names below to add or remove contacts to the basket.
            </TextBlock>
            <ListBox Grid.Row="1" x:Name="ContactList" SelectionMode="Multiple" Width="480" HorizontalAlignment="Left" Margin="0,5,0,0">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left">
            <TextBlock x:Name="OutputText" Style="{StaticResource SubheaderTextStyle}"/>
        </Grid>
    </Grid>

  修改后台代码:

View Code
    public sealed partial class ContactPickerPage : Page
    {
        CoreDispatcher dispatcher = Window.Current.Dispatcher;

        public ContactPickerPage()
        {
            this.InitializeComponent();

            ContactList.ItemsSource = contactSet;
            ContactList.SelectionChanged += ContactList_SelectionChanged;
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            contactPickerUI.ContactRemoved += contactPickerUI_ContactRemoved;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            contactPickerUI.ContactRemoved -= contactPickerUI_ContactRemoved;
        }

        async void contactPickerUI_ContactRemoved(ContactPickerUI sender, ContactRemovedEventArgs args)
        {
            // The event handler may be invoked on a background thread, so use the Dispatcher to run the UI-related code on the UI thread.
            string removedId = args.Id;
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                foreach (RefactorContact contact in ContactList.SelectedItems)
                {
                    if (contact.Id == removedId)
                    {
                        ContactList.SelectedItems.Remove(contact);
                        OutputText.Text += "\n" + contact.Name + " was removed from the basket";
                        break;
                    }
                }
            });
        }

        void ContactList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (RefactorContact added in e.AddedItems)
            {
                AddSampleContact(added);
            }

            foreach (RefactorContact removed in e.RemovedItems)
            {
                if (contactPickerUI.ContainsContact(removed.Id))
                {
                    contactPickerUI.RemoveContact(removed.Id);
                    OutputText.Text = removed.Name + " was removed from the basket";
                }
            }
        }

        void AppendValue(Contact contact, string value, ContactFieldType type, ContactFieldCategory category)
        {
            if (!string.IsNullOrEmpty(value))
            {
                contact.Fields.Add(new ContactField(value, type, category));
            }
        }

        void AddSampleContact(RefactorContact sampleContact)
        {
            Contact contact = new Contact();
            contact.Name = sampleContact.Name;

            AppendValue(contact, sampleContact.HomeEmail, ContactFieldType.Email, ContactFieldCategory.Home);
            AppendValue(contact, sampleContact.WorkEmail, ContactFieldType.Email, ContactFieldCategory.Work);

            AppendValue(contact, sampleContact.HomePhone, ContactFieldType.PhoneNumber, ContactFieldCategory.Home);
            AppendValue(contact, sampleContact.MobilePhone, ContactFieldType.PhoneNumber, ContactFieldCategory.Mobile);
            AppendValue(contact, sampleContact.WorkPhone, ContactFieldType.PhoneNumber, ContactFieldCategory.Work);

            if (!string.IsNullOrEmpty(sampleContact.Address))
            {
                contact.Fields.Add(new ContactLocationField(sampleContact.Address, ContactFieldCategory.None,
                    sampleContact.Street, sampleContact.City, sampleContact.State, "", sampleContact.ZipCode));
            }

            switch (contactPickerUI.AddContact(sampleContact.Id, contact))
            {
                case AddContactResult.Added:
                    // Notify the user that the contact was added
                    OutputText.Text = sampleContact.Name + " was added to the basket";
                    break;
                case AddContactResult.AlreadyAdded:
                    // Notify the user that the contact is already added
                    OutputText.Text = sampleContact.Name + " is already in the basket";
                    break;
                case AddContactResult.Unavailable:
                default:
                    // Notify the user that the basket is unavailable
                    OutputText.Text = sampleContact.Name + " could not be added to the basket";
                    break;
            }
        }        
    }

9)修改Package.appxmanifest,添加联系人选择器:

10)修改App的后台代码

View Code
        protected override void OnActivated(IActivatedEventArgs args)
        {
            if (args.Kind == ActivationKind.Protocol)
            {
                ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;

                var rootFrame = new Frame();
                rootFrame.Navigate(typeof(ItemsPage), "AllGroups");
                ItemsPage ip = rootFrame.Content as ItemsPage;
                ip.Frame.Navigate(typeof(SplitPage), "AssociationLaunching囧ProtocolActivated");
                SplitPage p = rootFrame.Content as SplitPage;
                Window.Current.Content = rootFrame;
                p.LoadFrame(typeof(Win8Api.AssociationLaunching.ReceiveUri), protocolArgs);
            }
            else if (args.Kind == ActivationKind.ContactPicker)
            {
                var page = new ContactPickerPage();
                page.Activate((ContactPickerActivatedEventArgs)args);
            }
            else
            {
                Window.Current.Activate();
            }
        }

11)添加联系人绑定适配器:ContactItemAdapter

View Code
    public class ContactItemAdapter
    {
        public string Name { get; private set; }
        public string SecondaryText { get; private set; }
        public BitmapImage Thumbnail { get; private set; }

        public ContactItemAdapter(ContactInformation contact)
        {
            Name = contact.Name;
            if (contact.Emails.Count > 0)
            {
                SecondaryText = contact.Emails[0].Value;
            }
            else if (contact.PhoneNumbers.Count > 0)
            {
                SecondaryText = contact.PhoneNumbers[0].Value;
            }
            else if (contact.Locations.Count > 0)
            {
                SecondaryText = contact.Locations[0].UnstructuredAddress;
            }
            GetThumbnail(contact);
        }

        private async void GetThumbnail(ContactInformation contact)
        {
            IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();
            Thumbnail = new BitmapImage();
            if (stream != null && stream.Size > 0)
            {                
                Thumbnail.SetSource(stream);
            }
            else
            {
                StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\logo.jpg");
                stream = await file.OpenReadAsync();
                Thumbnail.SetSource(stream);
            }
        }
    }

12)选择单个联系人

  我们使用ContactPicker的PickSingleContactAsync方法来选择单个联系人

  修改SinglePicker.xaml的xaml:

View Code
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                This sample demonstrates how to use the Contact Picker to select one contact. It includes a basic implementation
                of the Contact Picker APIs to demonstrate how to display a list of contacts to the user.
            </TextBlock>
            <Button Grid.Row="1" x:Name="PickAContactButton" Content="Pick contact" Margin="0,0,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Image x:Name="OutputThumbnail" Grid.Column="0" Stretch="UniformToFill" VerticalAlignment="Top" Width="64" HorizontalAlignment="Left"/>
            <StackPanel x:Name="OutputFields" Grid.Column="1" Margin="10,0,0,0">
                <TextBlock x:Name="OutputName" Style="{StaticResource HeaderTextStyle}" Margin="0,0,0,3"/>
                <TextBlock x:Name="OutputEmailHeader" Style="{StaticResource TitleTextStyle}" Visibility="Collapsed">Emails</TextBlock>
                <TextBlock x:Name="OutputEmails" Style="{StaticResource SubheaderTextStyle}"/>
                <TextBlock x:Name="OutputPhoneNumberHeader" Style="{StaticResource TitleTextStyle}" Visibility="Collapsed">Phone Numbers</TextBlock>
                <TextBlock x:Name="OutputPhoneNumbers" Style="{StaticResource SubheaderTextStyle}"/>
                <TextBlock x:Name="OutputAddressHeader" Style="{StaticResource TitleTextStyle}" Visibility="Collapsed">Addresses</TextBlock>
                <TextBlock x:Name="OutputAddresses" Style="{StaticResource SubheaderTextStyle}"/>
            </StackPanel>
            <TextBlock x:Name="OutputEmpty" Grid.Column="1" Style="{StaticResource SubheaderTextStyle}" Visibility="Collapsed">No contact was selected</TextBlock>
        </Grid>
    </Grid>

  修改后台代码:

View Code
    public sealed partial class SinglePicker : Page
    {
        public SinglePicker()
        {
            this.InitializeComponent();

            PickAContactButton.Click += PickAContactButton_Click;
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void PickAContactButton_Click(object sender, RoutedEventArgs e)
        {
            var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
            //"联系人选择器"用户界面确认按钮的文本
            contactPicker.CommitButtonText = "选择";
            //选择单个联系人
            ContactInformation contact = await contactPicker.PickSingleContactAsync();

            if (contact != null)
            {
                OutputFields.Visibility = Visibility.Visible;
                OutputEmpty.Visibility = Visibility.Collapsed;

                OutputName.Text = contact.Name;
                AppendContactFieldValues(OutputEmailHeader, OutputEmails, contact.Emails);
                AppendContactFieldValues(OutputPhoneNumberHeader, OutputPhoneNumbers, contact.PhoneNumbers);
                AppendContactFieldValues(OutputAddressHeader, OutputAddresses, contact.Locations);

                //获取联系人缩略图
                IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();
                BitmapImage bitmap = new BitmapImage();
                if (stream != null && stream.Size > 0)
                { 
                    bitmap.SetSource(stream);
                    OutputThumbnail.Source = bitmap;
                }
                else
                {
                    StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\logo.jpg");
                    stream = await file.OpenReadAsync();
                    bitmap.SetSource(stream);
                    OutputThumbnail.Source = bitmap;
                }
            }
            else
            {
                OutputEmpty.Visibility = Visibility.Visible;
                OutputFields.Visibility = Visibility.Collapsed;
                OutputThumbnail.Source = null;
            }
        }

        private void AppendContactFieldValues<T>(TextBlock header, TextBlock content, IReadOnlyCollection<T> fields)
        {
            if (fields.Count > 0)
            {
                StringBuilder output = new StringBuilder();
                foreach (IContactField field in fields)
                {
                    if (field.Type == ContactFieldType.Location)
                    {
                        AppendLocationValue(output, (ContactLocationField)field);
                    }
                    else
                    {
                        output.AppendFormat("{0} ({1})\n", field.Value, field.Category);
                    }
                }
                header.Visibility = Visibility.Visible;
                content.Visibility = Visibility.Visible;
                content.Text = output.ToString();
            }
            else
            {
                header.Visibility = Visibility.Collapsed;
                content.Visibility = Visibility.Collapsed;
            }
        }

        private void AppendLocationValue(StringBuilder output, ContactLocationField location)
        {
            string address = location.UnstructuredAddress;
            if (string.IsNullOrEmpty(address))
            {
                List<String> parts = (new List<string> { location.Street, location.City, location.Region, location.Country, location.PostalCode });
                address = string.Join(", ", parts.FindAll(s => !string.IsNullOrEmpty(s)));
            }
            output.AppendFormat("{0} ({1})\n", address, location.Category);
        }
    }

  效果图:

 

13)选择多个联系人

  我们使用ContactPicker的PickMultipleContactsAsync来选择多个联系人

  修改MultiplePicker.xaml的xaml:

View Code
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                This sample demonstrates how to use the Contact Picker to select multiple contacts. It includes a basic implementation
                of the Contact Picker APIs to demonstrate how to display a list of contacts to the user.
            </TextBlock>
            <Button Grid.Row="1" x:Name="PickContactsButton" Content="Pick contacts" Margin="0,0,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" Width="300" VerticalAlignment="Top" HorizontalAlignment="Left">
            <ListView x:Name="OutputContacts" SelectionMode="None">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid Width="300" Height="68" Margin="5,3,0,2">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Rectangle Grid.Column="0" Width="64" Height="64" Fill="Gray"/>
                            <Image Grid.Column="0" Width="64" Height="64" Source="{Binding Thumbnail}"/>
                            <StackPanel Grid.Column="1" Margin="10,4,0,0">
                                <TextBlock Style="{StaticResource SubheaderTextStyle}" Text="{Binding Name}"/>
                                <TextBlock Style="{StaticResource SubheaderTextStyle}" Text="{Binding SecondaryText}"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <TextBlock x:Name="OutputEmpty" Style="{StaticResource SubheaderTextStyle}" Visibility="Collapsed">No contacts were selected</TextBlock>
        </Grid>
    </Grid>

  修改后台代码:

View Code
    public sealed partial class MultiplePicker : Page
    {
        public IReadOnlyList<ContactInformation> contacts;

        public MultiplePicker()
        {
            this.InitializeComponent();
            PickContactsButton.Click += PickContactsButton_Click;
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void PickContactsButton_Click(object sender, RoutedEventArgs e)
        {
            var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
            contactPicker.CommitButtonText = "选择";
            contacts = await contactPicker.PickMultipleContactsAsync();

            OutputContacts.Items.Clear();

            if (contacts.Count > 0)
            {
                OutputEmpty.Visibility = Visibility.Collapsed;

                foreach (ContactInformation contact in contacts)
                {
                    OutputContacts.Items.Add(new ContactItemAdapter(contact));
                }
            }
            else
            {
                OutputEmpty.Visibility = Visibility.Visible;
            }
        }
    }

   效果图:

 

未完待续,敬请期待...
转载请注明出处:http://www.cnblogs.com/refactor/ 

posted on 2012-06-25 13:25  refactor  阅读(1188)  评论(0编辑  收藏  举报

导航