图解使用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类中的代码,
代码如下:
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:
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分布类:
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:
<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>
修改后台代码:
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的后台代码
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
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:
<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>
修改后台代码:
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:
<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>
修改后台代码:
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/