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

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

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

Лабораторная работа №7. Список задач

Задание

Создать приложение "Список задач" для Windows Phone 7 с возможностью добавления новых задач. Для установки даты и времени использовать элементы DatePicker и TimePicker библиотеки Microsoft.Phone.Controls.Toolkit.

Освоение

  • навигация между страницами
  • основные элементы управления и разметки (StackPanel, TextBox, TextBlock, ListBox, CheckBox, Button)
  • расширенные элементы управления (DatePicker, TimePicker)
  • события
  • меню приложения

Описание

Создадим новый проект Silverlight for Windows PhoneWindows Phone Application.

Приложение будет состоять из двух окон:

  • главное окно со списком задач
  • окно добавления новых задач

Откроем файл разметки главной страницы MainPage.xaml. В самом верху страницы разметки изменим выводимое название приложения, например, на "СПИСОК ЗАДАЧ". Заголовок страницы удалим или закомментируем с целью экономии места:

  <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="СПИСОК ЗАДАЧ" 
            Style="{StaticResource PhoneTextNormalStyle}"/>
            <!--TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" 
            Style="{StaticResource PhoneTextTitle1Style}"/-->
        </StackPanel>

Внутри элемента ContentPanel поместим элемент ListBox, который будем заполнять динамически из кода приложения (обязательно следует указать свойство Name, чтобы обращаться к списку из кода):

  <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <ListBox Name="listToDo" />
        </Grid>

Каждый элемент списка ListBoxItem будет включать панель StackPanel, которая будет объединять CheckBox с названием задачи, TextBlock с описанием и еще один TextBlock с датой и временем.

В конце страницы раскомментируем фрагмент кода, отвечающий за меню приложения. Зададим текст кнопок и объявим обработчики нажатия Click:

 <!--Sample code showing usage of ApplicationBar-->
    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" 
            Text="добавить" Click="MenuAdd_Click" />
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" 
            Text="удалить" Click="MenuRemove_Click" />

            <!--shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems-->
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>

Теперь перейдем к написанию кода.

Чтобы при создании новых задач передавать данные от страницы добавления к основной странице, создадим статический класс с 4 полями (заголовок, описание, дата и логический флаг, обозначающий, нужно ли создавать новый элемент):

 public static class ToDoItems
{
    public static bool NewItem;
    public static string Title;
    public static string Description;
    public static string DateTime;
}

Теперь откроем файл MainPage.xaml.cs. В самый верх для обеспечения перехода между страницами добавим директиву:

 using System.Windows.Navigation;

Переопределим метод OnNavigatedTo(), который вызывается при переходе на текущую страницу. В этом методе будем создавать новый элемент списка. Для этого последовательно будем создавать экземпляры CheckBox, TextBlock, StackPanel и ListBoxItem и задавать им необходимые свойства. Для того чтобы избежать добавления лишних элементов, будем использовать флаг ToDoItems.NewItem.

protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (ToDoItems.NewItem)
            {
                CheckBox chbNew = new CheckBox();
                chbNew.Content = ToDoItems.Title;
                chbNew.FontSize = 26;

                TextBlock tbNew1 = new TextBlock();
                tbNew1.Text = ToDoItems.Description;
                tbNew1.FontSize = 24;
                tbNew1.TextWrapping = TextWrapping.Wrap;

                TextBlock tbNew2 = new TextBlock();
                tbNew2.Text = ToDoItems.DateTime;
                tbNew2.FontSize = 24;
                tbNew2.FontStyle = FontStyles.Italic;

                StackPanel spNew = new StackPanel();
                spNew.Children.Add(chbNew);
                spNew.Children.Add(tbNew1);
                spNew.Children.Add(tbNew2);

                ListBoxItem lbiNew = new ListBoxItem();
                lbiNew.Content = spNew;

                listToDo.Items.Add(lbiNew);

                ToDoItems.NewItem = false;
            }
        }

В конструкторе проинициализируем флаг:

 // Constructor
        public MainPage()
        {
            ToDoItems.NewItem = false;

            InitializeComponent();
        }

Определим обработчики нажатий на кнопки меню. При нажатии на кнопку "Добавить" будем просто переходить на страницу добавления новой задачи (AddItem.xaml). При нажатии на кнопку "Удалить" будем сначала определять, выделен ли какой-нибудь элемент списка.

 private void MenuAdd_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/AddItem.xaml", UriKind.Relative));
        }

        private void MenuRemove_Click(object sender, EventArgs e)
        {
            if (-1 != listToDo.SelectedIndex)
            {
                listToDo.Items.RemoveAt(listToDo.SelectedIndex);
            }
            else
            {
                MessageBox.Show("Нет выделенных элементов.");
            }
        }

Теперь добавим в проект приложения новую страницу – Windows Phone Portrait Page. Назовем ее AddItem. В файле AddItem.xaml определим разметку страницы. Она будет включать два текстовых поля (для названия и описания задачи), DatePicker (для выбора даты), TimePicker (для выбора времени), 4 TextBlock (для пояснительных подписей) и две кнопки – "Принять" и "Отмена". Все элементы управления объединим с помощью StackPanel.

Чтобы элементы DatePicker и TimePicker стали доступны, необходимо скачать расширение Windows Phone Toolkit, что можно сделать, пройдя по ссылке:

http://silverlight.codeplex.com/releases

Затем в проект необходимо добавить в References библиотеку Microsoft.Phone.Controls.Toolkit Рис. 3.1:

Добавление в Reference библиотеку

Рис. 3.1. Добавление в Reference библиотеку

В самый верх файла разметки необходимо добавить строчку:

 xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

Примечание: Вместо "toolkit" можно придумать любое другое название. В этом случае на странице разметки при использовании элементов управления из данного пространства имен нужно использовать соответствующее указанное название.

Итак, страница разметки теперь примет вид:

 <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="СПИСОК ЗАДАЧ"
             Style="{StaticResource PhoneTextNormalStyle}"/>
            <!--TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/-->
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel Margin="15,15,0,0">
                <TextBlock Name="NotificationTitleCaption" Text="Заголовок:" FontSize="26" />
                <TextBox Name="txtTitle" FontSize="26" />

                <TextBlock Text="Текст:"  FontSize="26" />
                <TextBox Name="txtText" FontSize="26" />

                <TextBlock Text="Дата:" FontSize="26" VerticalAlignment="Center" />
                <toolkit:DatePicker Name="ToDoItemDate"/>
                <TextBlock Text="Время:" FontSize="26" VerticalAlignment="Center" />
                <toolkit:TimePicker Name="ToDoItemTime"/>

                <StackPanel Orientation="Horizontal" Margin="0,20,0,0">
                    <Button Name="btnSet" Content="Принять" Width="220" Click="btnSet_Click" />
                    <Button Name="btnBack" Content="Отмена" Width="220" Click="btnBack_Click" />
                </StackPanel>
            </StackPanel>
        </Grid>

Перейдем к коду страницы AddItem.xaml.cs.

Определим обработчики нажатий на кнопки. При нажатии на кнопку "Назад" будем спрашивать у пользователя подтверждения и переходить на главную страницу посредством вызова метода NavigationService.GoBack(). При нажатии на кнопку "Принять" будем проверять, что текстовые поля заполнены, объединять дату и время и в случае, если выбранное время еще не наступило, переходить на главную страницу. Переход будем осуществлять посредством метода NavigationService.GoBack(). В этом случае список на главной странице не будет очищаться.

private void btnBack_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Изменения будут потеряны. Продолжить?", 
"Отмена", MessageBoxButton.OKCancel);
            if (result == MessageBoxResult.OK)
            {
                NavigationService.GoBack();
            }
        }

        private void btnSet_Click(object sender, RoutedEventArgs e)
        {
            if (!txtTitle.Text.Trim().Equals("") && !txtText.Text.Trim().Equals(""))
            {
                DateTime date = (DateTime)ToDoItemDate.Value;
                DateTime time = (DateTime)ToDoItemTime.Value;
                DateTime beginTime = date + time.TimeOfDay;

                if (beginTime > DateTime.Now)
                {
                    ToDoItems.NewItem = true;
                    ToDoItems.Title = txtTitle.Text.Trim();
                    ToDoItems.Description = txtText.Text;
                    ToDoItems.DateTime = beginTime.ToString();

                    NavigationService.GoBack();
                }
                else
                {
                    MessageBox.Show("Невозможно установить задачу на прошлое.");
                }
            }
            else
            {
                MessageBox.Show("Не все поля заполнены.");
            }
        }

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

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