實驗3:搜索和共享
2012年9月
簡介
Windows 8用戶體驗的關鍵特點之一是對超級按鈕的使用。它響應輕掃或Windows徽標+C鍵,並從屏幕右側滑出。這些按鈕(“超級按鈕”)為Windows應用商店應用提供了一種以一致方式在應用程序之間公開常用功能的手段。例如,如果您需要在應用程序中執行搜素,您可以選擇搜索超級按鈕並在搜索窗格中輸入一個搜索條目。用戶界面和調用上述界面的操作在每個應用程序中都是一樣的。為了與另一個應用程序共享數據,您使用共享超級按鈕。一個支持共享的應用程序就可以共享數據了。例如,一個繪圖應用程序可以與其他支持共享的應用程序共享圖畫,或者Contoso Cookbook可以與其他支持共享的應用程序共享食譜,
在本實驗中,您將為Contoso Cookbook添加搜索和共享支持。您將獲得實現搜索和共享合約的第一手體驗。您將同時學習這些合約如何為兩個應用程序之間或應用程序與Windows自身之間提供更高層次的集成。
目標
本實驗將向您展示如何:
在Windows應用商店應用中實現共享
在Windows應用商店應用中實現搜索
實現搜索建議
系統要求
您需要下列軟件完成本實驗:
Microsoft Windows 8
Microsoft Visual Studio 2012
設置
您必須執行以下步驟來准備本實驗室的計算機:
1.安裝Microsoft Windows 8。
2.安裝Microsoft Visual Studio 2012。
練習
本動手實驗包含以下練習:
1.添加食譜共享
2.添加食譜搜索
完成本實驗的預計時間:30至40分鐘。
練習1:添加食譜共享
在練習1中您將向Contoso Cookbook添加共享支持,這樣食譜就可以被其他應用程序共享。您將對每個食譜共享兩類數據:包含食譜名稱、原料以及指南的文字數據和代表食譜圖形的圖像數據。
任務1–調用共享超級按鈕
首先,讓我們查看共享支持被添加之前,當共享超級按鈕在Contoso Cookbook中被調用時,它的行為方式。
1、在Visual Studio中打開您在實驗2中完成的ContosoCookbook項目。如果您尚未完成實驗2或希望從一個參考副本開始,您可以在開始材料中找到實驗已完成的版本。
2、按F5以啟動Contoso Cookbook。
3、點擊某個食譜以顯示項-明細頁面。
4、從屏幕右側從右向左輕掃以顯示超級按鈕,或按Windows徽標+C鍵。
5、點擊共享超級按鈕以顯示共享窗格。
6、由於Contoso Cookbook目前尚未實現共享合約,共享窗格通知您“此應用無法共享。”
7、返回Visual Studio並停止調試。
任務2 – 實現食譜共享
現在您已經查看了當某個應用程序不支持共享時共享窗格的外觀,讓我們向Contoso Cookbook添加共享合約。首先,我們需要添加一些基礎設施以支持上述合約。
1、打開ItemDetailPage.xaml.cs並在文件的頂部添加以下using語句。
C#
using Windows.ApplicationModel.DataTransfer;
using System.Text;
using Windows.Storage.Streams;
2、找到LoadState方法並在最後添加以下語句。
C#
// Register for DataRequested events
DataTransferManager.GetForCurrentView().DataRequested += OnDataRequested;
查看本欄目
3、現在向ItemDetailPage類添加以下方法。
C#
void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var request = args.Request; var item = (RecipeDataItem)this.flipView.SelectedItem; request.Data.Properties.Title = item.Title; request.Data.Properties.Description = "Recipe ingredients and directions"; // Share recipe text var recipe = "\r\nINGREDIENTS\r\n"; recipe += String.Join("\r\n", item.Ingredients); recipe += ("\r\n\r\nDIRECTIONS\r\n" + item.Directions); request.Data.SetText(recipe); }
注意:您通過為DataTransferManager的 DataRequested事件注冊一個處理程序以實現共享。當用戶激活共享超級按鈕時,這些事件將被觸發。在本例中,您通過調用由args.Request.Data公開的 DataPackage對象的SetText方法以響應上述事件並以文字方式提供食譜信息。當包含共享目標列表的共享窗格出現時,列表僅包含能夠使用文本的共享目標。
4、找到SaveState方法並在方法最後添加以下語句。
C#
// Deregister the DataRequested event handler
DataTransferManager.GetForCurrentView().DataRequested -= OnDataRequested;
5、按F5以啟動應用程序。
6、點擊某個食譜以顯示食譜-明細頁面。
7、顯示超級按鈕並選擇共享超級按鈕以顯示共享窗格。共享窗格現在顯示安裝在您設備上的共享目標列表,共享目標指可以使用共享源共享的數據的應用程序。
注意:如果您還未執行以上操作,現在就可以安裝Windows 8 SDK示例包中的共享目標示例(Share Target Sample)應用程序。共享目標示例應用程序演示了如何編寫可作為共享目標的應用程序。更重要的是它提供了一個共享目標以測試您開發的作為共享源的應用程序。它可以接收圖像、文本以及其他數據類型。如果需要安裝此示例,在Visual Studio中打開它並運行一次。然後當您從Windows應用商店應用選擇共享超級按鈕時,它就會出現在共享目標列表中。
8、在共享窗格中選擇一個共享目標並驗證它將收到食譜數據。圖1顯示了在接收Contoso Cookbook的食譜文本後的共享目標示例應用程序。
圖1 顯示某個食譜的共享目標示例應用程序
查看本欄目
9、返回Visual Studio並停止調試。
Contoso Cookbook現在可以共享文本食譜數據,但是由於每個食譜有一個圖像,它應該也能夠共享食譜圖像。這樣接收圖像的共享目標就可以顯示食譜的一張圖片和食譜文本(假設共享目標支持文本和圖像)。讓我們修改共享代碼以支持位圖圖像和文本。
1、返回在之前任務中添加的OnDataRequested方法。
2、在方法最後添加以下語句。
C#
// Share recipe image
var reference = RandomAccessStreamReference.CreateFromUri(new Uri(item.ImagePath.AbsoluteUri));
request.Data.Properties.Thumbnail = reference;
request.Data.SetBitmap(reference);
3、按F5以啟動應用程序。
4、點擊某個食譜以顯示食譜-明細頁面。
5、顯示超級按鈕並選擇共享超級按鈕以顯示共享窗格。
6、在共享窗格中選擇一個共享目標並驗證它將收到食譜圖像。圖2顯示了在接收Contoso Cookbook的食譜圖像後的共享目標示例應用程序。
圖2 顯示某個食譜圖像的共享目標示例應用程序
7、返回Visual Studio並停止調試。
查看本欄目
練習 2: 添加食譜搜索
在練習2中您將向Contoso Cookbook添加搜索支持,這樣用戶就可以使用搜索超級按鈕對食譜數據進行搜索。例如想在所有食譜中找到含糖食譜的用戶可以調用搜索超級按鈕,在搜索框中輸入“sugar”,含糖食譜列表就會被呈現給用戶。
在向Contoso Cookbook添加搜索支持前,讓我們查看當Contoso Cookbook在前台運行且搜索超級按鈕被調用時搜索用戶界面的外觀。
1、按F5以啟動應用程序。
2、從屏幕右側從右向左輕掃以顯示超級按鈕,或按Windows徽標+C鍵。
3、點擊搜索超級按鈕以顯示搜索窗格。
4、在搜索框中輸入“sugar”(不含引號)並按回車,或點擊搜索框右側的放大鏡圖標。
5、Windows告訴您“無法搜索此應用。”一旦當您向Contoso Cookbook添加搜索支持後結果就會改變。
6、返回Visual Studio並停止調試。
現在讓我們在Contoso Cookbook中實現搜索合約。Visual Studio將通過在應用程序中插入一個C#合約為您完成絕大部分工作。您需要調整代碼以針對應用程序數據執行特定的搜索。它實現起來很簡單,在接下來的幾步中將進行演示。
1、在解決方案管理器中右鍵單擊項目並使用Add > New Item命令添加名稱為SearchResultsPage.xaml的合約,如圖3所示。
圖3 添加一個搜索合約
2、在SearchResultsPage.xaml的<Pages.Resources>部分,在名稱為“AppName”的字符串資源中,將“My Application”修改為“Search”以修改頁面頂部的標題。
XAML
<x:String x:Key="AppName">Search</x:String>
3、向名稱為“resultsGridView”的GridView和名稱為“resultsListView”的ListView添加ItemClick=”OnItemClick”屬性。當應用程序未被貼靠時,GridView顯示搜索結果,當應用程序被貼靠時,ListView用於顯示搜索結果。
4、打開SearchResultsPage.xaml.cs並向SearchResultsPage類添加以下方法,以在搜索結果頁面中單擊某個項時導航至食譜頁面。
C#
private void OnItemClick(object sender, ItemClickEventArgs e)
{
// Navigate to the page showing the recipe that was clicked
this.Frame.Navigate(typeof(ItemDetailPage), ((RecipeDataItem)e.ClickedItem).UniqueId);
}
查看本欄目
5、在SearchResultsPage.xaml.cs的頂部添加以下using語句。
C#
using ContosoCookbook.Data;
6、接著向SearchResultsPage類添加以下字段。
C#
// Collection of RecipeDataItem collections representing search results
private Dictionary<string, List<RecipeDataItem>> _results = new Dictionary<string, List<RecipeDataItem>>();
7、轉至LoadState方法並在“Communicate results through the view model.”注釋前添加以下語句。
C#
// Search recipes and tabulate results var groups = RecipeDataSource.GetGroups("AllGroups"); string query = queryText.ToLower(); var all = new List<RecipeDataItem>(); _results.Add("All", all); foreach (var group in groups) { var items = new List<RecipeDataItem>(); _results.Add(group.Title, items); foreach (var item in group.Items) { if (item.Title.ToLower().Contains(query) || item.Directions.ToLower().Contains(query)) { all.Add(item); items.Add(item); } } filterList.Add(new Filter(group.Title, items.Count, false)); } filterList[0].Count = all.Count;
注意:您剛添加的代碼根據用戶輸入的查詢文本對所有食譜標題和指南進行搜索。對每個匹配的食譜,它將向變量名為all的食譜列表添加一個RecipeDataItem,並在每個特定組中向變量名為items的食譜列表添加一個RecipeDataItem。上述列表在您剛聲明的字典中被維護,並根據“All”, “Chinese”等組名稱被標記。
上述代碼同時填充搜索結果頁面頂部的篩選列表(由filterList變量代表),篩選列表包含組名稱,並顯示每個組中匹配的食譜數。
8、找到Filter_SelectionChanged方法並向if子句(緊挨在// TODO: Respond to the change in active filter注釋後)添加以下語句。
C#
this.DefaultViewModel["Results"] = _results[selectedFilter.Name];
9、在Common文件夾中打開StandardStyles.xaml。
10、找到名稱為“StandardSmallIcon300x70ItemTemplate”的DataTemplate。刪除綁定到Subtitle屬性的TextBlock。同時修改Border的width和height屬性,以及將第一個TextBlock的Text屬性綁定到ShortTitle而非Title。
XAML
<DataTemplate x:Key="StandardSmallIcon300x70ItemTemplate"> <Grid Width="294" Margin="6"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,0,0,10" Width="60" Height="45"> <Image Source="{Binding Image}" Stretch="UniformToFill" /> </Border> <StackPanel Grid.Column="1" Margin="10,-10,0,0"> <TextBlock Text="{Binding ShortTitle}" Style="{StaticResource BodyTextStyle}" TextWrapping="NoWrap" /> <TextBlock Text="{Binding Description}" Style="{StaticResource BodyTextStyle}" Foreground="{StaticResource ApplicationSecondaryForegroundThemeBrush}" TextWrapping="NoWrap" /> </StackPanel> </Grid> </DataTemplate>
11、按F5以啟動應用程序。
12、顯示超級按鈕。
13、點擊搜索超級按鈕並顯示搜索窗格。
14、在搜索窗格頂部的搜索框中輸入“sugar”(不含引號)並按回車,或點擊搜索框右側的放大鏡圖標。
15、驗證五個食譜出現在搜索結果中(見圖4)。
圖4 針對 “sugar”的搜索結果
16、選擇其中的某個食譜並驗證食譜明細將出現。
17、返回Visual Studio並停止調試。
查看本欄目
一個可以添加至搜索體驗的有用的增強是當用戶在搜索框中輸入一個搜索條目時提供相應的搜索建議。它實現起來很簡單。您需要做的就是為SuggestionsRequested事件注冊一個處理程序。下面是它的實現方法。
1、打開App.xaml.cs並在文件頂部添加以下using語句。
C#
using Windows.ApplicationModel.Search;
2、在OnLaunched方法的開始處緊挨著加載食譜數據的RecipeDataSource.LoadLocalDataAsync或RecipeDataSource.LoadRemoteDataAsync的調用後,添加以下語句。
C#
// Register handler for SuggestionsRequested events from the search pane
SearchPane.GetForCurrentView().SuggestionsRequested += OnSuggestionsRequested;
3、現在向Application類添加以下方法。
C#
void OnSuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) { string query = args.QueryText.ToLower(); string[] terms = { "salt", "pepper", "water", "egg", "vinegar", "flour", "rice", "sugar", "oil" }; foreach(var term in terms) { if (term.StartsWith(query)) args.Request.SearchSuggestionCollection.AppendQuerySuggestion(term); } }
注意:您剛添加的代碼為匹配salt, pepper, water, egg, vinegar, flour, rice, sugar和oil等模式的單詞提供搜索建議。如果用戶輸入“sa”,單詞“salt”將作為建議的完整條目出現在搜索窗格。當然只要您願意,您可以添加盡可能多的建議。如果您希望在用戶輸入“ke”時出現“ketchup”,只需簡單地向列表中添加該條目。
4、再次啟動應用程序並在搜索框中輸入“su”。驗證“sugar”將出現在搜索框下面的建議列表中,如圖5所示。
圖5 運行中的搜索建議
5、返回Visual Studio並停止調試。
查看本欄目
您快完成工作了,但仍然需要執行一項任務。目前當Contoso Cookbook運行時搜索工作良好。但是如果用戶從應用程序外調用搜索,它根本不能工作。為親自查看,確認Contoso Cookbook未運行(您可以在任務管理器中對它進行檢查,如果需要可以結束該任務)。然後調用搜索超級按鈕,在搜索框中輸入“sugar”,並在搜索窗格的應用程序列表中點擊Contoso Cookbook。您將注意到沒有符合搜索的結果。讓我們進行修改。
1、打開App.xaml.cs並找到OnSearchActivated方法。
注意:OnSearchActivated是Application類中一個關鍵的虛擬方法。當用戶執行搜索時它被調用以激活搜索結果頁面,並且它在您向項目添加搜索合約時被添加至App.xaml.cs。如果操作系統從搜索窗格啟動Contoso Cookbook,OnSearchActivated將替代OnLaunched而被調用。如果發生這種情況,在激活搜索結果頁面前,我們需要重新初始化應用程序。
2、在OnSearchActivated方法的開始部分添加以下語句。
C#
// Reinitialize the app if a new instance was launched for search if (args.PreviousExecutionState == ApplicationExecutionState.NotRunning || args.PreviousExecutionState == ApplicationExecutionState.ClosedByUser || args.PreviousExecutionState == ApplicationExecutionState.Terminated) { // Load recipe data await RecipeDataSource.LoadLocalDataAsync(); // Register handler for SuggestionsRequested events from the search pane SearchPane.GetForCurrentView().SuggestionsRequested += OnSuggestionsRequested; }
注意:如果您希望從雲中而不是從本地資源加載食譜數據,在以上代碼中用LoadRemoteDataAsync調用替換LoadLocalDataAsync調用,與您在實驗1中的做法一樣。
3、使用任務管理器以確認Contoso Cookbook未運行。如果運行則結束該任務。
4、轉至開始屏幕。顯示超級按鈕並點擊搜索超級按鈕。
5、輸入搜索條目“sugar”。然後在搜索窗格的應用程序列表中點擊Contoso Cookbook。
6、驗證Contoso Cookbook將會被啟動並顯示正確的搜索結果。
7、按Alt-F4關閉應用程序。
總結
合約是Windows 8的重要組成部分,因為它們允許應用程序與操作系統進行集成,並且它們提供了應用程序間一致並可預見的用戶體驗。這個松耦合的協作是非常協同和可擴展的,它允許您與任何應用程序共享任何內容,在任何應用內搜索。
在本實驗中您學習了兩類合約:共享合約和搜索合約。在以後的實驗中,您將使用另一類合約以對設置進行集成。但是首先還有其他內容需要處理:使用大多數內置於PC和移動設備的照相機實現媒體捕獲。這是下一個實驗的主題,因此讓我們繼續前進!
作者:cnblogs zigzagPath