Опубликован: 11.01.2013 | Доступ: свободный | Студентов: 623 / 124 | Длительность: 12:06:00
Лекция 4:

Лабораторный практикум 3

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Лабораторная работа №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("Контакт не выбран.");
            }
        }

Теперь можно скомпилировать приложение, запустить на эмуляторе или телефоне и проверить его функциональность.

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >