Лабораторный практикум 3
Лабораторная работа №13. Контакты и локальная база
Задание
Изменить приложение "Телефонная книжка", добавив возможность позвонить и отправить sms выбранному контакту, а также возможность выбрать фотографию из фотоальбома.
Освоение
- задачи запуска
- задачи выбора
Описание
Откроем существующий проект "Телефонная книжка". Добавим в файл разметки главной страницы место для фотографии (Image):
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Name="listContacts" Height="615">
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<Image Width="70" Height="70" />
<StackPanel Margin="10,7,10,7">
<TextBlock Text="Андреев Андрей" FontSize="28" />
<TextBlock Text="+79215555555" FontSize="22" Margin="50,0,0,0" />
</StackPanel>
</StackPanel>
</ListBoxItem>
</ListBox>
</Grid>
Также добавим элементы меню "Позвонить" и "Сообщение":
<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar.add.rest.png" Text="Добавить"
Click="ApplicationBarMenuAdd_Click" />
<shell:ApplicationBarIconButton IconUri="/Images/appbar.edit.rest.png" Text="Изменить"
Click="ApplicationBarMenuEdit_Click" />
<shell:ApplicationBarIconButton IconUri="/Images/appbar.delete.rest.png" Text="Удалить"
Click="ApplicationBarMenuRemove_Click" />
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Позвонить" Click="MenuCall_Click" />
<shell:ApplicationBarMenuItem Text="Сообщение" Click="MenuSMS_Click" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
При нажатии на данные кнопки будем вызывать соответствующую задачу запуска (позвонить или отправить сообщение). Для этого в начало файла добавим директиву:
using Microsoft.Phone.Tasks;
Задачи запуска предоставляют доступ к программным возможностям платформы. Так, например, задача запуска PhoneCallTask позволяет позвонить на указанный номер телефона, а SmsComposeTask – отправить сообщение:
private void MenuCall_Click(object sender, EventArgs e)
{
int nIndex = listContacts.SelectedIndex;
if (-1 != nIndex)
{
PhoneCallTask call = new PhoneCallTask();
call.DisplayName = ((TextBlock)((StackPanel)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).
Children[1]).Children[0]).Text;
call.PhoneNumber = ((TextBlock)((StackPanel)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).
Children[1]).Children[1]).Text;
call.Show();
}
else
{
MessageBox.Show("Контакт не выбран.");
}
}
private void MenuSMS_Click(object sender, EventArgs e)
{
int nIndex = listContacts.SelectedIndex;
if (-1 != nIndex)
{
SmsComposeTask sms = new SmsComposeTask();
sms.To = ((TextBlock)((StackPanel)((StackPanel)((ListBoxItem)listContacts.SelectedItem)
.Content).Children[1]).Children[0]).Text;
sms.Body = "Текст сообщения...";
sms.Show();
}
else
{
MessageBox.Show("Контакт не выбран.");
}
}
Теперь добавим в статический класс Contact новое поле, в котором будем хранить ссылку на фотографию контакта:
public static string m_Photo;
Страницу PageEdit.xaml дополним кнопкой и текстовым полем:
<Grid ShowGridLines="False" Margin="0,20,0,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="340" />
</Grid.ColumnDefinitions>
<TextBlock Text="Имя:" Grid.Column="0" Grid.Row="0"
VerticalAlignment="Center" FontSize="24" />
<TextBlock Text="Телефон:" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Center" FontSize="24" />
<Button Name="btnPhoto" Content="..." Grid.Column="0"
Grid.Row="2" Click="btnPhoto_Click" />
<TextBox Name="txtName" Text="Имя" Grid.Column="1"
Grid.Row="0" />
<TextBox Name="txtPhone" Text="Телефон" InputScope="TelephoneNumber"
Grid.Column="1" Grid.Row="1" />
<TextBox Name="txtPhoto" Text="Фото" IsReadOnly="True"
Grid.Column="1" Grid.Row="2" />
</Grid>
При нажатии на кнопку btnPhoto будем осуществлять задачу выбора картинки из доступных альбомов. Для этого добавим в код директиву:
using Microsoft.Phone.Tasks;
Добавим в класс глобальную переменную:
private PhotoChooserTask photo;
В конструктор добавим инициализацию данной переменной и подпишемся на событие завершения выбора картинки:
photo = new PhotoChooserTask();
photo.Completed += new EventHandler<PhotoResult>(photo_Completed);
При нажатии на кнопку "…" будем вызывать задачу выбора, а при завершении выбора сохранять ссылку на картинку в текстовом поле и статическом поле класса Contact:
private void btnPhoto_Click(object sender, RoutedEventArgs e)
{
bSelectPhoto = true;
photo.Show();
}
void photo_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
txtPhoto.Text = e.OriginalFileName;
Contact.m_Photo = txtPhoto.Text;
}
}
При добавлении нового контакта будем передавать в функцию AddNewContact ссылку на картинку. Затем с помощью класса BitmapImage из пространства имен System.Windows.Media.Imaging будем присваивать свойству Source объекта типа Image (фотография контакта) изображение по ссылке. Аналогичные изменения следует внести и в функцию изменения выбранного контакта:
private void AddNewContact(string strName, string strPhone, string strImg = null)
{
StackPanel stkHorizNew = new StackPanel();
ListBoxItem lstitNew = new ListBoxItem();
StackPanel stkNew = new StackPanel();
TextBlock txtNameNew = new TextBlock();
TextBlock txtPhoneNew = new TextBlock();
txtNameNew.Text = strName;
txtNameNew.FontSize = 28;
txtPhoneNew.Text = strPhone;
txtPhoneNew.FontSize = 22;
txtPhoneNew.Margin = new Thickness(50, 0, 0, 0);
stkNew.Margin = new Thickness(10, 7, 10, 7);
stkNew.Children.Add(txtNameNew);
stkNew.Children.Add(txtPhoneNew);
Image imgNew = new Image();
imgNew.Width = 70;
imgNew.Height = 70;
if (null != strImg) imgNew.Source = new BitmapImage(new Uri(strImg));
stkHorizNew.Orientation = System.Windows.Controls.Orientation.Horizontal;
stkHorizNew.Children.Add(imgNew);
stkHorizNew.Children.Add(stkNew);
lstitNew.Content = stkHorizNew;
listContacts.Items.Add(lstitNew);
listContacts.SelectedIndex = listContacts.Items.Count - 1;
}
Между страницами приложения будем осуществлять передачу ссылки на картинку (так же как это делаем с именем контакта и телефоном). Однако немного изменим поведение при передаче параметров с главной страницы. Поскольку к ссылке на картинку автоматически добавляется "file://" и все обратные слеши "\" заменяются на прямые "/" (а мы не хотим показывать такие изменения пользователю), будем убирать первые 7 символов ссылки и заменять слеши перед передачей.
// Меню - Добавить
private void ApplicationBarMenuAdd_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/PageEdit.xaml?mode=add", UriKind.Relative));
}
// Меню - Изменить
private void ApplicationBarMenuEdit_Click(object sender, EventArgs e)
{
int nIndex = listContacts.SelectedIndex;
if (-1 != nIndex)
{
string strName = ((TextBlock)((StackPanel)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).
Children[1]).Children[0]).Text;
string strPhone = ((TextBlock)((StackPanel)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).
Children[1]).Children[1]).Text;
string strPhoto = "";
if(null != ((Image)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).Children.ElementAt(0)).Source)
{
strPhoto = ((BitmapImage)((Image)((StackPanel)((ListBoxItem)listContacts.SelectedItem).Content).
Children.ElementAt(0)).Source).UriSource.AbsoluteUri;
if (strPhoto.Substring(0, 7).Equals("file://"))
{
strPhoto = strPhoto.Substring(7);
strPhoto = strPhoto.Replace('/', '\\');
}
}
Contact.m_Id = nIndex;
Contact.m_Name = strName;
Contact.m_Phone = strPhone;
Contact.m_Photo = strPhoto;
NavigationService.Navigate(new Uri("/PageEdit.xaml?mode=edit", UriKind.Relative));
}
else
{
MessageBox.Show("Контакт не выбран.");
}
}
Теперь можно скомпилировать приложение, запустить на эмуляторе или телефоне и проверить его функциональность.