Будьте добры сообщите какой срок проверки заданий и каким способом я буду оповещен! |
Поиск и общий доступ
XAML+C#. Практическое занятие №5
Задание: продолжая проект, полученный в результате выполнения четвертого практического задания, добавьте поддержку контрактов поиска и общего доступа в приложение.
- В качестве подтверждения выполнения лабораторной работы от вас потребуется предоставить скриншот страницы отдельного элемента (ItemDetailPage.xaml) в режиме вызова контракта общего доступа.
ЗАМЕЧАНИЕ: напоминаем, что ваше приложение должно быть уникальным:
- Использовать в качестве источников данных источники, отличные от тех, которые приводятся в инструкциям к практическим занятиям
- Внешний вид приложения должен соответствовать выбранной вами тематике приложения (для всех страниц приложения).
- Политика конфиденциальности (Privacy Policy) должна соответствовать вашему приложению и быть доступна внутри приложения.
Добавление поиска
Пришло время добавить в приложение контракт поиска. Сделать это достаточно просто. Надо добавить в проект новый Item типа Search Contract:
При этом добавится страница отображения поиска, которую я назвал MySearchResultsPage.xaml.
Если после добавления контракта собрать приложение и попытаться по нему искать, отобразится именно эта страница. Причем, поскольку мы не добавили никакой логики отображения — она будет пустая.
Давайте теперь добавим логику, по которой будет происходить поиск. Для простоты мы будем отрабатывать сценарий поиска в уже работающем приложении, предполагая, что данные из RSS находятся в памяти приложения.
Сначала удалим лишнее определения названия приложения со страницы MySearchResultsPage.xaml, у нас эта переменная уже определена в App.xaml:
<Page.Resources> <CollectionViewSource x:Name="resultsViewSource" Source="{Binding Results}"/> <CollectionViewSource x:Name="filtersViewSource" Source="{Binding Filters}"/> <common:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <!-- TODO: Update the following string to be the name of your app --> </Page.Resources>
Далее, модифицируем класс Filter, который определен в MySearchResultsPage.xaml.cs, так, чтобы он отдавал список Item нашего типа:
private sealed class Filter<T> : MyReader.Common.BindableBase { private String _name; private bool _active; private List<T> _results; public Filter(String name, IEnumerable<T> results, bool active = false) { this.Name = name; this.Active = active; this.Results = results.ToList(); } public List<T> Results { get { return _results; } set { if (this.SetProperty(ref _results, value)) this.OnPropertyChanged("Description"); } } public override String ToString() { return Description; } public String Name { get { return _name; } set { if (this.SetProperty(ref _name, value)) this.OnPropertyChanged("Description"); } } public int Count { get { return _results.Count; } } public bool Active { get { return _active; } set { this.SetProperty(ref _active, value); } } public String Description { get { return String.Format("{0} ({1})", _name, this.Count); } } }
Не забудьте добавить в блок using директиву:
using MyReader.Data;
Теперь собственно необходимо определить логику поиска в методе LoadState файла MySearchResultsPage.xaml.cs:
var filterList = new List<Filter<RSSDataItem>>( from feed in RSSDataSource.AllGroups select new Filter<RSSDataItem>(feed.Title, feed.Items.Where(item => (item.Title != null && item.Title.Contains(queryText) || (item.Content != null && item.Content.Contains(queryText)))), false)); filterList.Insert(0, new Filter<RSSDataItem>("All", filterList.SelectMany(f => f.Results), true));
А в обработчике Filter_SelectionChanged изменить обращение к фильтру в соответсвии с нашими изменениями выше, а также присвоить полученный результат this.DefaultViewModel["Results"] :
var selectedFilter = e.AddedItems.FirstOrDefault() as Filter<RSSDataItem>; this.DefaultViewModel["Results"] = selectedFilter.Results;
Если теперь запустить приложение, и воспользоваться чудо-кнопкой поиска, мы сможем увидеть следующее:
При выборе результатов поиска, у нас не происходит перехода на соответствующую страницу записи, поскольку мы не обрабатываем это событие. Давайте добавим этот функционал. Для этого определим обработчик события ItemClick для resultsGridView: :
<GridView> x:Name="resultsGridView" AutomationProperties.AutomationId="ResultsGridView" AutomationProperties.Name="Search Results" TabIndex="1" Grid.Row="1" Margin="0,-238,0,0" Padding="110,240,110,46" SelectionMode="None" IsSwipeEnabled="false" IsItemClickEnabled="True" ItemsSource="{Binding Source={StaticResource resultsViewSource}}" ItemTemplate="{StaticResource StandardSmallIcon300x70ItemTemplate}" ItemClick="resultsGridView_ItemClick">
И в коде:
private void resultsGridView_ItemClick(object sender, ItemClickEventArgs e) { var itemId = ((RSSDataItem)e.ClickedItem).UniqueId; this.Frame.Navigate(typeof(ItemDetailPage), itemId); }
Теперь можно запустить приложение и проверить, что все работает, как ожидается.
Добавление общего доступа
Зарегистрируем обработчик события DataRequested в NavigateTo страницы (и отпишемся от события в NavigateFrom), и реализуем обработчик в котором предоставим системе название поста и текст:
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); DataTransferManager.GetForCurrentView().DataRequested += Share_DataRequested; } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); DataTransferManager.GetForCurrentView().DataRequested -= Share_DataRequested; } private void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var selectedItem = (RSSDataItem)this.flipView.SelectedItem; args.Request.Data.Properties.Title = selectedItem.Title; args.Request.Data.Properties.Description = selectedItem.Content; args.Request.Data.SetText(selectedItem.Content); }
Запустите приложение перейдите на страницу поста и проверьте, что теперь приложение может передать данные в другие приложения.
На самом деле мы получаем гораздо больше данных для расшаривания в RSS фиде. Это картинка поста, URI поста и т.д. Предлагаю самостоятельно модифицировать код метода добавляния фида, а также сопутствующие классы, чтобы было больше данных. Больше данных – с большим количеством приложений можно поделиться!