понедельник, 24 сентября 2012 г.

Контракты в Windows 8 приложениях (Search)

Сегодня я хотел бы поговорить о еще одном контракте предоставляемом операционной системой для Windows 8 приложений. Этим контрактом будет поиск. Ну а так как современное приложение сложно представить без этого функционала, то вперед.

 Для демонстрации, создадим пустое приложение Windows 8. Кликаем правой клавишей на проекте, выбираем добавить новый элемент, ну а в открывшемся окне нам остается найти элемент Search Contract и дать имя странице, которая будет использоваться для отображения результатов поиска:
Соответственно, если открыть файл манифеста и перейти в закладку Declarations, можно увидеть свежедобавленный контракт:
Замечательной новостью является, что настраивать дополнительно его нет необходимости.
Открываем страницу поиска и по уже сложившейся традиции удаляем из XAML все, кроме корневого Grid. В связанном cs файле, также удаляем из класса все, кроме метода LoadState, да и в нем, оставляем только первую строку.
Данный метод будет вызываться каждый раз, как будет начинаться поиск в нашем приложении.
Начнем, с реализации донаборщика при поиске. Для этого, я добавил в свое приложение три картинки, а также класс, описывающий некую задачу с ID, именем, исполнителем и иконкой:

class MyTask

{
    public string ID { get; set; }
 
    public string Title { get; set; }
 
    public string Owner { get; set; }
 
    public string Image { get; set; }
 
    public static IEnumerable<MyTask> CreateTask()
    {
        List<MyTask> list = new List<MyTask>();
        list.Add(new MyTask() { ID = "1", Title = "Встретится с Димой", Owner = "Алексей", Image = "meeting.png" });
        list.Add(new MyTask() { ID = "2", Title = "Позвонить Оле", Owner = "Алексей", Image = "call.png" });
        list.Add(new MyTask() { ID = "3", Title = "Встретится с Сашей", Owner = "Алексей", Image = "meeting.png" });
        list.Add(new MyTask() { ID = "4", Title = "Встретится с Колей", Owner = "Алексей", Image = "meeting.png" });
        list.Add(new MyTask() { ID = "5", Title = "Купить хлеб", Owner = "Алексей", Image = "note.png" });
        list.Add(new MyTask() { ID = "6", Title = "Купить молока", Owner = "Алексей", Image = "note.png" });
        list.Add(new MyTask() { ID = "7", Title = "Написать статью", Owner = "Алексей", Image = "note.png" });
        list.Add(new MyTask() { ID = "8", Title = "Позвонить Даше", Owner = "Алексей", Image = "call.png" });
        return list;
    }
}

Все, на главной странице подписываемся на запрос донаборщика:

private SearchPane searchPane;

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    searchPane = SearchPane.GetForCurrentView();
    searchPane.SuggestionsRequested += searchPane_SuggestionsRequested;
}

Ну и пишем в обработчике подсовывание вариантов донабора:

private void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
{
    string enteredText = args.QueryText;
    if (!string.IsNullOrWhiteSpace(enteredText))
    {
        foreach (var task in MyTask.CreateTask().Where(t => t.Title.ToLower().Contains(enteredText.ToLower())))
        {
            args.Request.SearchSuggestionCollection.AppendResultSuggestion(
                task.Title,
                "Ответственный: " + task.Owner,
                task.ID,
                RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///" + task.Image, UriKind.Absolute)),
                task.Image.Replace(".png", ""));
        }
    }
}

Список будет сам очищаться после каждого введенного пользователем символа, нам нужно только добавлять. Ну и если нет такой расширенной информации как в примере, то можно воспользоваться перегруженной командой AppendResultSuggestion, которая принимает только строку.
Все, теперь, если запустить наше приложение и открыть поиск, то мы увидим вот такую картинку (черному фону не удивляйтесь, у нас ведь на главной странице ничего нет):

А если начнем набирать, например "Позвонить", то вот такую:
Замечательно, донаборщик работает. Осталось реализовать просмотр результатов поиска.
Для этого на добавленную страницу впишем следующий код:

<Grid Style="{StaticResource LayoutRootStyle}">
    <GridView ItemsSource="{Binding SearchResult}">
        <GridView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding ID}" Margin="5" />
                    <TextBlock Text="{Binding Title}" Margin="5" />
                    <TextBlock Text="{Binding Owner}" Margin="5" />
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
</Grid>
Ну и обработчик полученного запроса:
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
 
var queryText = navigationParameter as String;
DefaultViewModel["SearchResult"] = MyTask.CreateTask().Where(t => t.Title.ToLower().Contains(queryText.ToLower()));
}
Все. Запускаем, открываем поиск, вводим текст, смотрим на донаборщик (если надо, что можно выбрать из предложенных вариантов) и нажав Enter, получаем автоматический переход на страницу поиска:

Вроде все, что хотел рассказал. Удачного программирования!

 

Комментариев нет:

Отправить комментарий