The Contacts
class allows you to search the user’s contacts for a string. The search can be restricted to a single field of the Contact
class, or to contacts that have been pinned to the phone’s Start Experience (home screen). Searches are performed using one of the following FilterKind
enumeration values:
None
(default value)
DisplayName
EmailAddress
PhoneNumber
PinnedToStart
To query the user’s contact list, define a Contacts
instance as a field in a class, as shown:
Contacts contacts;
Instantiate the Contacts
object, subscribe to its SearchCompleted
event, and then call SearchAsync
, as shown in the following excerpt:
void SearchContacts()
{
contacts = new Contacts();
contacts.SearchCompleted += HandleSearchCompleted;
contacts.SearchAsync("andrew", FilterKind.DisplayName, null);
}
Note
To access the user’s contact list the ID_CAP_CONTACTS capability must be present in the WMAppManifest.xml file.
For more information on the phone’s security capability model, see Chapter 2, “Fundamental Concepts in Windows Phone Development.”
The Contacts.SearchAsync
method allows the use of an empty search string when FilterKind
is set to DisplayName, PinnedToStart, or None. An exception is raised if you attempt to search for an empty string in conjunction with a FilterKind
value equal to EmailAddress or PhoneNumber.
When the search completes, the specified event handler receives a list of matching Contact
objects. See the following excerpt:
void HandleSearchCompleted(object sender, ContactsSearchEventArgs e)
{
if (e.Results == null)
{
return;
}
Contacts = e.Results;
}
The list of retrieved Contact
objects can be further refined using LINQ.
Note
Be mindful that when using LINQ, however, some users may have a lot of contacts, and it may be expensive to use LINQ to select a subset of the resulting Contact
objects.
Internally, the contact list has various indexes placed on fields corresponding to the FilterKind
enumeration, which may offer superior performance during retrieval. Therefore, favor the use of filters rather than LINQ wherever possible.
Windows Phone aggregates contacts from various social networking accounts, including Windows Live, Facebook, Twitter, and LinkedIn (and potentially more to come). To determine the accounts from which contacts are available, use the Contacts
class’s Accounts
property.
The example for this section allows the user to enter a search string, select a FilterKind
enumeration value, and perform a search against the user’s contact list.
Within the ContactsViewModel
class a SearchText
property and a FilterKind
property restrict the results of the call to contacts.SearchAsync
(see Listing 14.7).
The list of available filter values is exposed by the viewmodel’s FilterKinds
property.
A DelegateCommand
named SearchCommand
calls the SearchContacts
method when it is executed. When the SearchCompleted
handler is called, a Contacts
property is populated with the result.
public class ContactsViewModel : ViewModelBase
{
public ContactsViewModel() : base("search contacts")
{
searchCommand = new DelegateCommand(arg => SearchContacts());
}
Contacts contacts;
void SearchContacts()
{
if (string.IsNullOrWhiteSpace(searchText)
&& (FilterKind == FilterKind.EmailAddress
|| FilterKind == FilterKind.PhoneNumber))
{
MessageService.ShowMessage("Please enter the search text.");
return;
}
contacts = new Contacts();
contacts.SearchCompleted += HandleSearchCompleted;
contacts.SearchAsync(searchText, FilterKind, null);
}
void HandleSearchCompleted(object sender, ContactsSearchEventArgs e)
{
if (e.Results == null)
{
return;
}
Contacts = e.Results;
}
IEnumerable<Contact> contactsList = new List<Contact>();
public IEnumerable<Contact> Contacts
{
get
{
return contactsList;
}
private set
{
Assign(ref contactsList, value);
}
}
readonly DelegateCommand searchCommand;
public ICommand SearchCommand
{
get
{
return searchCommand;
}
}
string searchText;
public string SearchText
{
get
{
return searchText;
}
set
{
Assign(ref searchText, value);
}
}
FilterKind filterKind = filterKinds.First();
public FilterKind FilterKind
{
get
{
return filterKind;
}
set
{
Assign(ref filterKind, value);
}
}
static readonly IEnumerable<FilterKind> filterKinds
= EnumUtility.CreateEnumValueList<FilterKind>().OrderBy(x => x.ToString());
public IEnumerable<FilterKind> FilterKinds
{
get
{
return filterKinds;
}
}
}
The view contains a TextBox
that is bound to the viewmodel’s SearchText
property and a ListPicker
whose ItemsSource
property is bound to the FilterKinds
viewmodel property (see Listing 14.8).
When the user selects an item in the ListPicker
, the viewmodel’s FilterKind
property is updated.
Results are displayed using a ListBox
, whose ItemsSource
property is bound to the viewmodel’s Contacts
property. Each Content
object is presented using a TextBlock
to show its DisplayName
, and a ListBox
is used to display each of the contact’s email addresses.
<StackPanel x:Name="ContentPanel" Grid.Row="1">
<TextBlock Text="search" Style="{StaticResource LabelTextStyle}" />
<TextBox Text="{Binding SearchText, Mode=TwoWay}" />
<toolkit:ListPicker
ItemsSource="{Binding FilterKinds}"
SelectedItem="{Binding FilterKind, Mode=TwoWay}"
Header="filter" />
<ListBox ItemsSource="{Binding Contacts}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,20">
<TextBlock Text="{Binding DisplayName}"
Style="{StaticResource PhoneTextLargeStyle}" />
<ListBox ItemsSource="{Binding EmailAddresses}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding EmailAddress}"
Style="{StaticResource PhoneTextNormalStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
In addition, the view contains an AppBarIconButton
that is bound to the viewmodel’s SearchCommand
, as shown:
<u:AppBar>
<u:AppBarIconButton
Command="{Binding SearchCommand}"
Text="search"
IconUri="/Images/ApplicationBarIcons/AppBarSearch.png" />
</u:AppBar>
When the user taps the application bar button, matching contacts are displayed at the bottom of the page (see Figure 14.35).
3.147.7.154