Pull to refresh

Начало Windows Phone 8 Development: урок 4. Связь с сервисами и привязка к данным

Reading time 5 min
Views 13K
Original author: Bandar Alsharfi
Начало Windows Phone 8 Development: урок 1. Макет приложения и обработчик событий
Начало Windows Phone 8 Development: урок 2. Доступ к локальному хранилищу приложения
Начало Windows Phone 8 Development: урок 3. Навигация по страницам и передача параметров
Начало Windows Phone 8 Development: урок 4. Связь с сервисами и привязка к данным

Как и было обещано, к концу этого урока Вы уже будете себя чувствовать почти настоящим разработчиком под Windows Phone 8 ). Сейчас мы уже умеем строить GUI используя XAML, создавать обработчики событий, переходить по страницам, сохранять данные в локальном хранилище. Все, что осталось освоить, что б создавать настоящие приложения – это привязка к данным и взаимодействие между сервисами.

Что такое привязка к данным?



Помните описание новостного приложения из урока 3? У нас есть множество новостей, которые необходимо показать пользователю. Первое, с чем нужно разобраться – это как новости будут выглядеть и как их показывать пользователю. Как на меня, новсть должна состоять из заголовка, краткого описания, возможно картинки, и что то вроде кнопки Подробно.

Процесс привязки новостей к UI (пользовательский интерфейс) — это и есть процесс привязки данных.

Однако, из-за известных причин мы не можем показать сразу все новости со всеми подробностями на одной странице, так как пользователю придется использовать достаточно длинную прокрутку, что б прочитать всё. Это решается путем использования двух страниц — на одной просто список новостей, на другой — подробности выбранной новости.

Как осуществить привязку данных?



Для начала определим list box. Учтите, что можно задать, как именно будет выглядеть список внутри тега ListBox.ItemTemplate. DataTemplate (Шаблон данных) будет содержать план привязки данных. Для привязки элемента управления, сначала находим атрибут, который нужно привязать, например картинка (image) к элементу управления Image, а текст привяжем к элементу управления TextBlock.

image

Код
<ListBox x:Name="NewsList" Height="490"   
                   HorizontalAlignment="Left"
                   Margin="5,25,0,0" VerticalAlignment="Top" Width="444"
                   SelectionChanged="NewsList_SelectionChange" >
          <ListBox.ItemTemplate>
                   <DataTemplate>
                              <StackPanel Orientation="Horizontal"
                                                      VerticalAlignment="Top" >
                                          <Image Sourse="{Binding Thumb}" Height="60" Stretch="Fill" >
                                                      <TextBlock Text="{Binding Title}" FontSize="20"
                                                                           TextWrapping="Wrap" >
                               </StackPanel>
                    </DataTemplate>
           </ListBox.ItemTemplate>  
</ListBox>



Тут я использую StackPanel для шаблона пунктов содержания: картинка, а рядом с ней TextBlock. Выглядит это следующим образом:

image

Использование службы WCF



Что такое WCF рассказывать не буду, но вот что этот сервис делает — расскажу. Ленивая загрузка кода и его проверка. У меня есть класс, названный WindowsPhoneLessonNews, который содержит свойства Title(Название), Content(Содержание), Thumb. Так же имеется 2 операции: одна для загрузки всех новостей, а вторая — для загрузки новости по её индексу.

Добавим ссылку на наш сервис, что б можно было его использовать. Правой кнопкой на References и выбираем пункт Add Service Reference.

image

Мои сервисы размещены на локальном сервисе с портом 8080. Перейдите на сервис и выберите его. У меня название сервиса Lesson4PhoneNewsService.

image

Теперь, когда добавили ссылку на сервис, можем начать его использовать. Для начало разберемся, что происходит при загрузке страницы. Скорее всего, Вы уже заметили, что я использую асинхронный вызов для получения всех новостей. Из-за использования асинхронного вызова необходимо убедиться, что мы не блокируем GUI, пока не получим ответ от сервиса.

image

Код
        private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e)
        {
            NewsServiceClient newsClient = new NewsServiceClient;
            newsClient.GetAllNewsCompleted += newsClient_GetAllNewsCompleted;
            newsClient.GetAllNewsAsync();
            ProgressLoader.Visibility = Visibility.Visible;
            ProgressLoader.IsIndeterminate = true;
        }



Что б загрузка не была сильно скучной для пользователя — добавим полосу загрузки: она будет анимироваться, пока идет получение данных, если же получения данных нету — то полоса становится невидимой.

image

Код
        </ListBox.ItemTemplate>
    </listBox>
    <ProgressBar x:namespace="ProgressLoader" Height="10" Visibility="Collapsed"/>



Еще одной особенности асинхронного программирования является то, что необходимо указать приложению, что делать после получения ответа от сервиса. Я буду просто присваивать ItemsSource нашего ListBox результат ответа, который получаем от сервиса и прятать полосу загрузки.

image

Код
        void newsClient_GetAllNewsCompleted(object sender, GetAllNewsCompletedEventArgs e)
        {
            NewsList.ItemSourse = e.Result;
            NewsList.SelectedIndex = -1;
            ProgressLoader.Visibility = Visibility.Collapsed;
            ProgressLoader.IsIndeterminate = false;
        }



Так же я знаю, что сервис возвращает list(список), поэтому сразу же прикрепляю ответ к ListBox.

А что произойдет, если нажать на новость?



Давайте создадим обработчик события при нажатии на новость. Проверяем валидность индекса и перенаправляем пользователя на страницу, одновременно передавая индекс как параметр, где показывается полная информация. Таким образом, страница NewsDetails сможет определить какую именно новость показать полностью.

image

Код
        private void News_List_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(NewsList.SelectedIndex != 1)
                NavigationService.Navigate(new Uri(string.Format("/NewsDetails.xaml?NewsId={0}", NewsList.SelectedIndex.ToString()), UriKind.Relative));
        }



image

Код
        private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e)
        {
            NewsServiceClient client = new NewsServiceClient();
            client.GetNewsByIDCompleted += client_GetNewsByIDCompleted;
            client.GetNewsByIDAsunc(int.Parse(NavigationContext.QueryString["NewsID"].ToString()));
        }



И почти такое же, когда доходит до асинхронного вызова:
image

Код
        void client_GetNewsByIDCompleted(object sender, GetNewsByIDCompletedEventArgs e)
        {
            List<WindowsPhoneLessonNews> selectedNews = new List<WindowsPhoneLessonNews>();
            selectedNews.Add(e.Result);
            NewsList.ItemSource = selectedNews;
        }



Если хотите вернуться на предыдущую страницу — нажмите кнопку Назад на телефоне.

Поработаем над внешним видом



Далее представлен макет главной страницы, состоящий из TextBlock, который говорит, что контент получается от веб-сервиса и тд….

image

Код
        <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBlock Text="List is being populated from the web service, tap" TextWrapping="Wrap" Padding="0,0,10,0"> </Textбlock> 
            <ListBox x:Name="WewsList" Height="490" HorizontalAlignment="Left" Margin="5,25,0,0" VerticalAlignment="Top" Width="444" SelectionChanged="WewsList_SelectionChanged" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal"
                                    VerticalAlignment="Top">
                            <Image Source="{Binding Thumb}" Height="60" Stretch="Fill"/> 
                                <TextBlock Text="{Binding Title}" FontSize="20" TextWrapping="Wrap"/> 
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate> 
             </ListBox> 
             <ProgressBar x:Name="ProgressLoader" Height="10" Visibility="Collapsed"/>
        </StackPanel>



Страница NewsDetails. Почти идентичный XAML главной страницы. Изменена ориентация StackPanel на вертикальную, вырезаны картинки и добавлено содержимое новости. А еще изменен размер шрифта на 40 для заголовка.

Тестируем!



image

Если нажать на нужную новость, откроется страница с подробной информацией:

image

Подведем итоги всех 4 уроков



И так, теперь у Вас есть достаточно знаний, что б написать свое приложение для Windows Phone 8, используя XAML, визуальный редактор страниц, макеты, обработчики событий, навигацию, привязку данных.

Надеюсь Вам помогли мои уроки и Вы сможете отталкиваясь от них саморазвиваться и самосовершенствоваться.

Удачи.
Tags:
Hubs:
+1
Comments 0
Comments Leave a comment

Articles