注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

Windows8:基于C#的Search Contract实现  

2011-11-24 10:07:57|  分类: Windows 8 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

本文主要介绍基于XAML+C#实现SearchContract功能。关于Windows8的Search Contract,《Windows8:Search - 让你的Ap拥有完美的搜索体验》一文中有详细的介绍,并且文中提供了HTML5+Javascript的代码实现。


Search Contract的设置及处理事件如下:

Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~
下面的内容将会针对这几项设置和这些事件贴代码介绍。

首先声明接收Charm菜单上的Search事件(在User点击Search按钮或者选择SearchAp的时候都会发生)。
打开工程中Package.appxmanifest文件,在“Declarations栏位”添加Search,如下图:
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

完成操作后Package.appxmanifest文件中相关代码:
<Extensions>
  <Extension Category="windows.search" />
</Extensions>


App.xaml.cs文件中,重写OnSearchActivated函数来接收系统发送的Search Activation事件。OnSearchActivated在Ap的Search页面未出现的两种情况下会触发(在SearchPage秀出来之后不再被调用):
1. 点击Search按钮;
2. 点选SearchAp项。
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

OnSearchActivated函数完整代码:
protected override async void OnSearchActivated(SearchActivatedEventArgs args)
{
    base.OnSearchActivated(args);
    await EnsureSearchPageActive(args);
    ((SearchPage)Window.Current.Content).UpdateTitle(args.QueryText);
}
其中EnsureSearchPageActive(args)函数用于呼叫SearchPage。也可以用主页面来承载查询结果,但是为了方便管理,这里我用一个自定义页面SearchPage.xaml来实现Search。
EnsureSearchPageActive函数体:
private async Task EnsureSearchPageActive(IActivatedEventArgs args)
{
    if (args.PreviousExecutionState != ApplicationExecutionState.Terminated)
    {
        Window.Current.Content = new SearchPage();
        Window.Current.Activate();
    }
}
这里的IActivatedEventArgs.PreviousExecutionState标识Ap状态,Ap最好在ApplicationExecutionState.Terminated状态下重新载入在Suspending时候保存的数据,但是这里只是Search的Demo,不对Ap状态做相应处理了。

前一段代码中UpdateTile()是一个自定义的函数,用于更新在Search不同字串时显示在SearchPage中的Title信息。当然这里也可以作为查询数据并展示的入口点。

SearchPane有一个小细节,就是在输入框可以自定义提示文字,告诉User可以输入什么来做Search,实现很简单,直接贴上代码:

searchPane.PlaceholderText = "input whatever you want";

效果如下:
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

在User做Search动作时,有几个事件点是作为一个SearchAp应当关心的:
1. 查询字串改变(QueryChanged);
2. 提交查询的动作(QuerySubmitted);
3. 选择某个查询建议(ResultSuggestionChosen);
4. 系统在User键入字串时要求Ap提供搜索建议(SuggestionsRequested);
5. 右边Search的bar被收起或展开(VisibilityChanged)。
从上到下,这5个事件分别有5个EventHandler来接收和处理:
1. TypedEventHandler<SearchPane, SearchPaneQueryChangedEventArgs> QueryChanged
2. TypedEventHandler<SearchPane, SearchPaneQuerySubmittedEventArgs> QuerySubmitted
3. TypedEventHandler<SearchPane, SearchPaneResultSuggestionChosenEventArgs> ResultSuggestionChosen
4. TypedEventHandler<SearchPane, SearchPaneSuggestionsRequestedEventArgs> SuggestionsRequested
5. TypedEventHandler<SearchPane, SearchPaneVisibilityChangedEventArgs> VisibilityChanged

可以从系统获取到SearchPane类来接收这些事件,示例代码:
SearchPane searchPane = SearchPane.GetForCurrentView();
searchPane.SuggestionsRequested += new TypedEventHandler<SearchPane, SearchPaneSuggestionsRequestedEventArgs>(searchPane_SuggestionsRequested);
// other event handler....

为了给User提供最好的用户体验,我们有必要在User键入搜索时提供搜索建议,下面就是实现搜索建议的简单代码:
void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
{
    string[] suggestionList = { "Acer", "Amazon", "Apple", "ASUS", "BenQ", "Canon", "Dell", "Ericsson", "Fujifilm", "Verizon", "Nvidia", "IBM" };
    //args.Request.SearchSuggestionCollection.AppendQuerySuggestions(suggestionList);
    int nSuggestionSize = 0;
    foreach (string suggestion in suggestionList)
    {
        //if(suggestion.Contains(args.QueryText))
        if (suggestion.StartsWith(args.QueryText, StringComparison.CurrentCultureIgnoreCase))
        {
            args.Request.SearchSuggestionCollection.AppendQuerySuggestion(suggestion);
            if (++nSuggestionSize == 2)
            {
                args.Request.SearchSuggestionCollection.AppendSearchSeparator("I'm a Separator ");
            }
        }
    }
    // .....
}
代码中:SearchSuggestionCollection.AppendQuerySuggestion()实现提供搜索建议词条;SearchSuggestionCollection.AppendSearchSeparator()可以在搜索建议中提供必要的分栏;而SearchSuggestionCollection.AppendQuerySuggestions()可以将一个数组全部加入搜索建议中。需要注意的是,现在搜索看起来只支持5条建议,开发者需要适宜地提供最合适的搜索建议。
以上代码的运行效果如下:
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

不知道还有没有人记得曾经百度大肆宣传过他们家的“框运算”,其实现在百度的搜索也确实一定程度上实现了这个目标,比如你输入“天气”,第一个显示的就是当地的天气情况;比如输入某某软件,就会直接显示它官网的下载按钮。这些搜索的动作本身就可以获取到User想要的结果,而不是再一次点击链接到相应的网站才能知道信息。

SearchContract中就有相似概念的一个方法:SearchSuggestionCollection类中的AppendResultSuggestion(string text, string detailText, string tag, StreamReference image, string imageAlternateText)。应用这个方法的简单代码,只需要在上面searchPane_SuggestionsRequested中加入两行代码:
StreamReference thumbnail = StreamReference.CreateFromUri(new Uri(Windows.ApplicationModel.Package.Current.InstalledLocation.Path + "\\Images\\Thumbnail.jpg"));
args.Request.SearchSuggestionCollection.AppendResultSuggestion("text", "detailText", "tag ABC123", thumbnail, "imageAlternateText");

SearchSuggestionCollection.AppendResultSuggestion的完整参数列表:
void AppendResultSuggestion(string text, string detailText, string tag, StreamReference image, string imageAlternateText);
其中,textdetailTextResultSuggestion的显示信息;tag是唯一标记,是User点击该ResultSuggestion而触发ResultSuggestionChosen事件时,程序收到的信息,从而页面可以显示出相应的结果;thumbnailResultSuggestion的显示图像,可以直观的区分QuerySuggestionResultSuggestionimageAlternateTextimage的附加信息,备用,功能不明。
以上代码的显示效果就是:
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

QuerySuggestionResultSuggestion虽然地位平等,但事实上有很大不同。前者告诉User搜索词条建议,后者告诉User可能的搜索结果;前者只能表现一个字串,后者可以有image、title和detail信息;前者通过字串告诉Ap用户的搜索关键字,而后者直接引导用户到Ap的搜索结果页面。开发者在使用时要分清场合。

需要再一次注意,QuerySuggestionResultSuggestionSuggestionSeperator再加上系统历史记录,在搜索建议上只能显示最多5条内容。长期试用之后系统历史记录会非常冗长,可以通过下面代码来关闭历史记录:
searchPane.SearchHistoryEnabled = false;

SearchPane还有一个属性对历史记录有影响:
string SearchHistoryContext { get; set; }
这个属性作为认定系统记录的第二个Key(第一个Key为AppId),也就是说同一支SearchAp的搜索历史记录可以保存有很多套,这个SearchHistoryContext既是用于确定使用哪一套历史记录。
在SearchContract中,本文最后一个推荐开发者使用的功能:
LocalContentSuggestionSettings settings = new LocalContentSuggestionSettings();
settings.Locations.Add(KnownFolders.MusicLibrary);
settings.AqsFilter = "kind:Music";
searchPane.SetLocalContentSuggestionSettings(settings);
设置SearchPaneLocalContentSuggestionSettings,并取消searchPane_SuggestionsRequested事件监听,可以让系统提供本地文件的搜索建议,LocalContentSuggestionSettings类包含了搜索范围:路径和文件格式。
当然,要搜索到本地文件还需要在Package.appxmanifest文件中开启对相应格式数据的读取权限,比如:
Windows8:基于C的Search Contract实现 - 乂乂 - 一个人,一支烟  ·~~

做了一个界面很简单的Demo,但是SearchContract的方法及功能都包含在内了。
如果有需要请留下邮箱地址,我可以提供完整的代码供参考。
  评论这张
 
阅读(2812)| 评论(16)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017