Retrieving Contacts

,

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:

Image None (default value)

Image DisplayName

Image EmailAddress

Image PhoneNumber

Image 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.”



Note

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.

Sample Contacts Page

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.

LISTING 14.7. ContactsViewModel Class


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.

LISTING 14.8. ContactsView.xaml (excerpt)


<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).

Image

FIGURE 14.35 ContactsView page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.7.154