zoukankan      html  css  js  c++  java
  • 重新想象 Windows 8 Store Apps (38)

    [源码下载]


    重新想象 Windows 8 Store Apps (38) - 契约: Search Contract



    作者:webabcd


    介绍
    重新想象 Windows 8 Store Apps 之 契约

    • Search Contract - 右侧边栏称之为 Charm, 其中的“搜索”称之为 Search Contract
    • 使用 Search Contract 的搜索建议,数据源在本地,以及从输入法编辑器中获取相关信息
    • 使用 Search Contract 的搜索建议,数据源在服务端,以及为搜索建议增加图标、描述等
    • 使用 Search Contract 的基于本地文件的搜索建议,数据来源于文件的 metadata



    示例
    1、演示 Search Contract 的基本应用
    Contracts/SearchContract/Demo.xaml

    <Page
        x:Class="XamlDemo.Contracts.SearchContract.Demo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Contracts.SearchContract"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <TextBlock Name="lblMsg" FontSize="14.667" Text="直接通过键盘输入即可激活 SearchPane" />
                
                <Button Name="btnShowSearch" Content="打开 SearchPane" Click="btnShowSearch_Click_1" Margin="0 10 0 0" />
                
            </StackPanel>
        </Grid>
    </Page>

    Contracts/SearchContract/Demo.xaml.cs

    /*
     * 本例演示 Search Contract 的基本应用
     * 
     * Search Contract - 右侧边栏称之为 Charm,其中的“搜索”称之为 Search Contract
     * 
     * 1、在 Package.appxmanifest 中新增一个“搜索”声明
     * 2、在 App.xaml.cs 中 override void OnSearchActivated(SearchActivatedEventArgs args),如果 app 是由搜索激活的,则可以在此获取相关的搜索信息
     * 
     * SearchActivatedEventArgs - 当 app 由搜索激活时的事件参数
     *     QueryText - 搜索文本
     *     PreviousExecutionState - 此 app 被搜索激活前的执行状态(ApplicationExecutionState 枚举:NotRunning, Running, Suspended, Terminated, ClosedByUser)
     *     SplashScreen - 启动画面对象
     * 
     * SearchPane - 搜索面板
     *     GetForCurrentView() - 获取当前的 SearchPane
     *     Show() - 显示搜索面板,需要的话可以指定初始查询字符串
     *     PlaceholderText - 当搜索框没有输入焦点且用户未输入任何字符时,搜索框中的提示文本
     *     SearchHistoryEnabled - 是否启用搜索建议的历史记录功能,默认值是 true
     *     SearchHistoryContext - 如果启用了搜索建议的历史记录功能,则此值用于指定历史纪录的上下文,即历史记录会在此上下文中保存和获取,也就是说一个 app 的搜索建议历史记录可以有多套
     *     ShowOnKeyboardInput - 如果发现键盘输入,是否激活搜索面板,默认值是 false
     *     Visible - 搜索面板是否是打开状态,只读
     *     QueryChanged - 搜索面板的搜索框中的文本发生变化时所触发的事件
     *     QuerySubmitted - 提交搜索面板的搜索框中的文本时所触发的事件
     *     VisibilityChanged - 打开或关闭搜索面板时所触发的事件
     */
    
    using System;
    using Windows.ApplicationModel.Activation;
    using Windows.ApplicationModel.Search;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Contracts.SearchContract
    {
        public sealed partial class Demo : Page
        {
            private SearchPane _searchPane;
    
            public Demo()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 获取当前的 SearchPane,并注册相关事件
                _searchPane = SearchPane.GetForCurrentView();
                _searchPane.QueryChanged += _searchPane_QueryChanged;
                _searchPane.QuerySubmitted += _searchPane_QuerySubmitted;
    
                // 当搜索框没有输入焦点且用户未输入任何字符时,搜索框中的提示文本
                _searchPane.PlaceholderText = "请输入";
    
                // 是否启用搜索建议的历史记录
                _searchPane.SearchHistoryEnabled = true;
                // 指定搜索建议的历史记录的上下文
                _searchPane.SearchHistoryContext = "abc";
    
                // 如果有键盘输入,则直接激活 SearchPane
                _searchPane.ShowOnKeyboardInput = true;
    
                // 通过搜索激活应用程序时(参见 App.xaml.cs 中的 OnSearchActivated() 方法)
                SearchActivatedEventArgs searchActivated = (SearchActivatedEventArgs)e.Parameter;
                if (searchActivated != null)
                    ShowSearchPane(searchActivated.QueryText);
            }
            
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 取消相关事件的监听
                _searchPane.QueryChanged -= _searchPane_QueryChanged;
                _searchPane.QuerySubmitted -= _searchPane_QuerySubmitted;
    
                _searchPane.ShowOnKeyboardInput = false;
            }
    
            private void btnShowSearch_Click_1(object sender, RoutedEventArgs e)
            {
                ShowSearchPane();
            }
    
            // 显示 Search 面板
            private void ShowSearchPane(string queryText="")
            {
                _searchPane.Show(queryText);
                lblMsg.Text = queryText;
            }
    
            void _searchPane_QueryChanged(SearchPane sender, SearchPaneQueryChangedEventArgs args)
            {
                lblMsg.Text = args.QueryText;
            }
    
            void _searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
            {
                lblMsg.Text = args.QueryText;
            }
        }
    }

    App.xaml.cs

    // 通过搜索激活应用程序时所调用的方法
    protected override void OnSearchActivated(SearchActivatedEventArgs args)
    {
        if (args.PreviousExecutionState == ApplicationExecutionState.Running)
            return;
    
        var rootFrame = new Frame();
        rootFrame.Navigate(typeof(MainPage), args);
        Window.Current.Content = rootFrame;
    
        Window.Current.Activate();
    }


    2、本例演示如何使用 Search Contract 的搜索建议,数据源在本地。同时演示如何从输入法编辑器中获取相关信息
    Contracts/SearchContract/LocalSuggestion.xaml

    <Page
        x:Class="XamlDemo.Contracts.SearchContract.LocalSuggestion"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Contracts.SearchContract"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <TextBlock Name="lblMsg" FontSize="14.667" Text="本例演示如何使用 Search Contract 的搜索建议,数据源在本地。同时演示如何从输入法编辑器中获取相关信息" />
                
            </StackPanel>
        </Grid>
    </Page>

    Contracts/SearchContract/LocalSuggestion.xaml.cs

    /*
     * 本例演示如何使用 Search Contract 的搜索建议,数据源在本地。同时演示如何从输入法编辑器中获取相关信息
     * 
     * SearchPane - 搜索面板
     *     SuggestionsRequested - 用户的查询文本发生改变,app 需要提供新的建议时所触发的事件(事件参数 SearchPaneSuggestionsRequestedEventArgs)
     *     QuerySubmitted - 提交搜索面板的搜索框中的文本时所触发的事件
     *     
     * SearchPaneSuggestionsRequestedEventArgs - 当需要提供新的建议时所触发的事件
     *     QueryText - 搜索文本
     *     Request - 关于建议信息的对象,返回 SearchPaneSuggestionsRequest 类型的数据
     *     SearchPaneQueryLinguisticDetails - 关于输入法编辑器信息(IME)的对象,返回 SearchPaneQueryLinguisticDetails 类型的数据
     *     
     * SearchPaneSuggestionsRequest - 关于建议信息的对象
     *     SearchSuggestionCollection - 搜索面板的搜索建议集合
     *         Size - 搜索建议的数量,最多只支持 5 个元素,就算超过 5 个系统也只会显示前 5 个
     *         AppendQuerySuggestion() & AppendQuerySuggestions() - 将指定的建议信息添加到搜索面板的建议集合中
     *         
     * SearchPaneQueryLinguisticDetails - 关于输入法编辑器(IME - Input Method Editor)信息的对象
     *     QueryTextAlternatives - 当前查询文本 IME 中的全部可能的文本列表
     *     QueryTextCompositionLength - 当前在 IME 中输入的查询文本的长度
     *     QueryTextCompositionStart - 当前在 IME 中输入的查询文本在整个查询字符串中的起始位置
     */
    
    using System;
    using Windows.ApplicationModel.Search;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Contracts.SearchContract
    {
        public sealed partial class LocalSuggestion : Page
        {
            private SearchPane _searchPane;
    
            private static readonly string[] suggestionList =
            {
                "beijing", "北京", "beiji", "北极", "shanghai", "上海", "tianjin", "天津", "chongqing", "重庆"
            };
    
            public LocalSuggestion()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 获取当前的 SearchPane,并注册相关事件
                _searchPane = SearchPane.GetForCurrentView();
                _searchPane.SuggestionsRequested += _searchPane_SuggestionsRequested;
                _searchPane.QuerySubmitted += _searchPane_QuerySubmitted;
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 取消相关事件的监听
                _searchPane.SuggestionsRequested -= _searchPane_SuggestionsRequested;
                _searchPane.QuerySubmitted -= _searchPane_QuerySubmitted;
            }
    
            void _searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
            {
                if (!string.IsNullOrEmpty(args.QueryText))
                {
                    // 根据用户当前的输入法编辑器中的内容,在建议列表中显示相关建议
                    foreach (string alternative in args.LinguisticDetails.QueryTextAlternatives)
                    {
                        foreach (string suggestion in suggestionList)
                        {
                            if (suggestion.StartsWith(alternative, StringComparison.CurrentCultureIgnoreCase))
                            {
                                args.Request.SearchSuggestionCollection.AppendQuerySuggestion(suggestion);
    
                                // 建议列表最多只支持 5 个元素,超过 5 个也只会显示前 5 个
                                if (args.Request.SearchSuggestionCollection.Size >= 5)
                                    break;
                            }
                        }
                    }
    
                    // 根据用户的当前输入,在建议列表中显示相关建议(不考虑输入法编辑器中的内容)
                    foreach (string suggestion in suggestionList)
                    {
                        if (suggestion.StartsWith(args.QueryText, StringComparison.CurrentCultureIgnoreCase))
                        {
                            args.Request.SearchSuggestionCollection.AppendQuerySuggestion(suggestion);
    
                            // 建议列表最多只支持 5 个元素,超过 5 个也只会显示前 5 个
                            if (args.Request.SearchSuggestionCollection.Size >= 5)
                                break;
                        }
                    }
                }
            }
    
            void _searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
            {
                lblMsg.Text = args.QueryText;
            }
        }
    }


    3、本例演示如何使用 Search Contract 的搜索建议,数据源在服务端。同时演示如何为搜索建议增加图标、描述等
    Contracts/SearchContract/RemoteSuggestion.xaml

    <Page
        x:Class="XamlDemo.Contracts.SearchContract.RemoteSuggestion"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Contracts.SearchContract"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <TextBlock Name="lblMsg" FontSize="14.667" Text="本例演示如何使用 Search Contract 的搜索建议,数据源在服务端。同时演示如何为搜索建议增加图标、描述等" />
    
            </StackPanel>
        </Grid>
    </Page>

    Contracts/SearchContract/RemoteSuggestion.xaml.cs

    /*
     * 本例演示如何使用 Search Contract 的搜索建议,数据源在服务端。同时演示如何为搜索建议增加图标、描述等
     * 
     * SearchPane - 搜索面板
     *     SuggestionsRequested - 用户的查询文本发生改变,app 需要提供新的建议时所触发的事件(事件参数 SearchPaneSuggestionsRequestedEventArgs)
     *     ResultSuggestionChosen - 提交搜索建议对象时所触发的事件(除了查询文本,还有图标和描述信息的)
     *         这里所谓的搜索建议对象就是通过 AppendResultSuggestion(string text, string detailText, string tag, IRandomAccessStreamReference image, string imageAlternateText) 构造的搜索建议
     *     QuerySubmitted - 提交搜索字符串时所触发的事件(只有文本信息的)
     *     
     * SearchPaneSuggestionsRequestedEventArgs - 当需要提供新的建议时所触发的事件
     *     QueryText - 搜索文本
     *     Request - 关于建议信息的对象,返回 SearchPaneSuggestionsRequest 类型的数据
     *     SearchPaneQueryLinguisticDetails - 关于输入法编辑器信息(IME)的对象,返回 SearchPaneQueryLinguisticDetails 类型的数据
     *     
     * SearchPaneSuggestionsRequest - 关于建议信息的对象
     *     SearchSuggestionCollection - 搜索面板的搜索建议集合
     *         Size - 搜索建议的数量,最多只支持 5 个元素,就算超过 5 个系统也只会显示前 5 个
     *         AppendQuerySuggestion() & AppendQuerySuggestions() - 将指定的建议信息添加到搜索面板的建议集合中
     *         AppendSearchSeparator() - 添加一个分割,可以指定分隔符左侧的文本
     *         AppendResultSuggestion(string text, string detailText, string tag, IRandomAccessStreamReference image, string imageAlternateText) - 增加一个搜索建议对象
     *             text - 建议结果的文本
     *             detailText - 描述
     *             tag - 附加数据,可以在 ResultSuggestionChosen 事件的事件参数中获取此值
     *             image - 图标
     *             imageAlternateText - 图像的替换文字
     *     GetDeferral() - 获取异步操作对象,同时开始异步操作,之后通过 Complete() 通知完成异步操作
     */
    
    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Windows.ApplicationModel.Search;
    using Windows.Data.Json;
    using Windows.Storage.Streams;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Contracts.SearchContract
    {
        public sealed partial class RemoteSuggestion : Page
        {
            private SearchPane _searchPane;
    
            // 用于获取远程建议的 HttpClient
            private HttpClient _httpClient;
            // 当前的 HttpClient 请求任务
            private Task<string> _currentHttpTask;
    
            public RemoteSuggestion()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 获取当前的 SearchPane,并注册相关事件
                _searchPane = SearchPane.GetForCurrentView();
                _searchPane.SuggestionsRequested += _searchPane_SuggestionsRequested;
    
                // 如果用户提交的搜索数据是通过 AppendResultSuggestion(string text, string detailText, string tag, IRandomAccessStreamReference image, string imageAlternateText) 而来的,则触发此事件
                _searchPane.ResultSuggestionChosen += _searchPane_ResultSuggestionChosen;
    
                // 如果用户提交的搜索数据是字符串,则触发此事件
                _searchPane.QuerySubmitted += _searchPane_QuerySubmitted;
    
                _httpClient = new HttpClient();
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                // 取消相关事件的监听
                _searchPane.SuggestionsRequested -= _searchPane_SuggestionsRequested;
                _searchPane.ResultSuggestionChosen -= _searchPane_ResultSuggestionChosen;
                _searchPane.QuerySubmitted -= _searchPane_QuerySubmitted;
    
                if (_httpClient != null)
                {
                    _httpClient.Dispose();
                    _httpClient = null;
                }
            }
    
            async void _searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
            {
                // 异步操作
                var deferral = args.Request.GetDeferral();
    
                try
                {
                    // 根据用户的输入,从远程获取建议列表
                    Task task = GetTaobaoSuggestionsAsync("http://suggest.taobao.com/sug?extras=1&code=utf-8&q=" + args.QueryText, args.Request.SearchSuggestionCollection);
                    await task;
    
                    lblMsg.Text = "TaskStatus: " + task.Status.ToString();
                }
                finally
                {
                    // 完成异步操作
                    deferral.Complete();
                }
            }
    
            void _searchPane_ResultSuggestionChosen(SearchPane sender, SearchPaneResultSuggestionChosenEventArgs args)
            {
                lblMsg.Text = "ResultSuggestionChosen: " + args.Tag;
            }
    
            void _searchPane_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
            {
                lblMsg.Text = "QuerySubmitted: " + args.QueryText;
            }
    
            private async Task GetTaobaoSuggestionsAsync(string str, SearchSuggestionCollection suggestions)
            {
                // 取消之前的 HttpClient 请求任务
                if (_currentHttpTask != null)
                    _currentHttpTask.AsAsyncOperation<string>().Cancel();
    
                // 新建一个 HttpClient 请求任务,以从远程获取建议列表数据
                _currentHttpTask = _httpClient.GetStringAsync(str);
                string response = await _currentHttpTask;
    
                // 将获取到的数据放到建议列表中
                JsonObject jb = JsonObject.Parse(response);
                var ary = jb["result"].GetArray();
                foreach (JsonValue jv in ary)
                {
                    // 图文方式显示建议数据
                    RandomAccessStreamReference imageStreamRef = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
                    suggestions.AppendResultSuggestion(jv.GetArray()[0].GetString(), "detailText", jv.GetArray()[0].GetString(), imageStreamRef, "imageAlternateText");
                    suggestions.AppendSearchSeparator("separator");
    
                    // 建议列表最多只支持 5 个元素,超过 5 个也只会显示前 5 个
                    if (suggestions.Size >= 5)
                        break;
                }
            }
        }
    }


    4、本例演示如何使用 Search Contract 的基于本地文件的搜索建议,数据来源于文件的 metadata
    Contracts/SearchContract/LocalFileSuggestion.xaml

    <Page
        x:Class="XamlDemo.Contracts.SearchContract.LocalFileSuggestion"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Contracts.SearchContract"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <TextBlock Name="lblMsg" FontSize="14.667" Text="本例演示如何使用 Search Contract 的基于本地文件的搜索建议,数据来源于文件的 metadata" />
    
            </StackPanel>
        </Grid>
    </Page>

    Contracts/Sear0chContract/LocalFileSuggestion.xaml.cs

    /* 
     * 本例演示如何使用 Search Contract 的基于本地文件的搜索建议,数据来源于文件的 metadata
     * 
     * SearchPane - 搜索面板
     *     SetLocalContentSuggestionSettings() - 指定一个 LocalContentSuggestionSettings 对象,以实现基于本地文件的搜索建议
     *    
     * LocalContentSuggestionSettings - 基于本地文件的搜索建议的相关配置
     *     Enabled - 是否启用
     *     Locations - 搜索路径
     *     AqsFilter - AQS 字符串,参见 http://msdn.microsoft.com/zh-cn/library/windows/apps/aa965711.aspx
     *     PropertiesToMatch - 用于提供搜索建议的文件属性列表,默认会使用所有可用的文件属性
     *     
     * 
     * 注:AQS 全称 Advanced Query Syntax
     */
    
    using Windows.ApplicationModel.Search;
    using Windows.Storage;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Contracts.SearchContract
    {
        public sealed partial class LocalFileSuggestion : Page
        {
            public LocalFileSuggestion()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 实例化 LocalContentSuggestionSettings
                var settings = new LocalContentSuggestionSettings();
                settings.Enabled = true;
    
                // 指定需要搜索的文件夹为 KnownFolders.MusicLibrary(需要在 Package.appxmanifest 的“功能”中选中“音乐库”)
                settings.Locations.Add(KnownFolders.MusicLibrary);
    
                // 在当前的 SearchPane 中启用指定的 LocalContentSuggestionSettings
                SearchPane.GetForCurrentView().SetLocalContentSuggestionSettings(settings);
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    log4j配置详解
    elasticsearch6.0版本安装head插件
    JAVA笔记-如何将百万级数据高效的导出到Excel表单
    抽象方法为什么不能被private与static修饰
    vue利用promise实现连续弹框
    vue代码片段
    h5元素高度超出屏幕但不滚动
    css3动画
    vue 引入静态图片404
    ios windows.open()不能打开
  • 原文地址:https://www.cnblogs.com/webabcd/p/3164297.html
Copyright © 2011-2022 走看看