如何使用 Windows Phone 的应用程序连接扩展搜索

2012/2/9

在 Windows Phone OS 7.1 中,应用程序可以使用“关联的应用”扩展 Windows Phone 上的搜索体验。本主题介绍如何创建启用“关联的应用”的应用程序并使用各种快速卡测试该应用程序:产品卡、地点卡和电影卡。本主题中特别推荐的应用程序从“关联的应用”深层链接 URI 中提取参数并将这些参数显示在应用程序页面上。有关使用“关联的应用”扩展搜索体验的过渡更多信息,请参阅 Windows Phone 的搜索可扩展性概述

重要说明重要说明:

如果应用程序滥用“关联的应用”,则可能会导致将其从商城中清除。您应只注册与您的应用程序相关的搜索扩展。若要详细了解 Bing 将哪些扩展与各种快速卡相关联,请试用快速卡示例

“关联的应用”旨在节省用户的时间。应用程序必须通过一种有意义的方式来使用“关联的应用”URI 参数。例如,可以使用“关联的应用”在您从快速卡启动自己的应用程序时自动在该应用程内搜索。使用快速卡示例可以详细了解从快速卡传递的 URI 参数值。

有关与每个快速卡关联的所有可用扩展和 URI 参数的列表,请参阅 Windows Phone 的搜索注册和启动引用

本主题包括以下主要步骤:

  1. 配置应用程序清单

  2. 创建 Extras.xml 文件

  3. 从快速卡映射 URI

  4. 创建数据模型

  5. 创建 ViewModel

  6. 创建快速卡目标页面

  7. 完成应用程序

  8. 使用快速卡进行测试

  9. 调试应用程序

提示提示:

本主题与快速卡示例相对应。若要下载完整的应用程序,请参阅 Windows Phone 的代码示例

在此过程中,您将修改或创建以下文件:

  • WMAppManifest.xml:修改此应用程序清单文件以指定与该应用程序相对应的搜索扩展。

  • Extensions\Extras.xml:创建此文件以指定将出现在相应快速卡的应用程序 Pivot 页面中的应用程序标题和说明。

  • App.xaml:修改此文件以指定从快速卡深层链接到快速卡目标页面的 URI 映射。

  • App.xaml.cs:修改此文件以在该应用程序中启用 URI 映射。

  • Model\QuickCardUriParameters.cs:创建此类文件以表示“关联的应用”深层链接 URI 中的参数。此类实现 INotifyPropertyChanged 接口。

  • ViewModel\QuickCardViewModel.cs:创建此类文件以表示快速卡目标页面的 ViewModel。此类从“关联的应用”深层链接 URI 中提取参数并实现 INotifyPropertyChanged 接口。

  • QuickCardTargetPage.xaml:创建快速卡目标页面并修改 XAML 代码以表示深层链接 URI 中的参数。对于 MVVM 模式,此页面为视图。

  • QuickCardTargetPage.xaml.cs:修改此页面以创建 ViewModel 对象并在页面加载时将参数加载到 ViewModel 中。

  • MainPage.xaml:修改此页面以表示用于标准应用程序启动的文本。此页面不是由“关联的应用”启动的。

本主题中创建的应用程序使用 Model-View-ViewModel (MVVM) 模式。有关 MVVM 应用程序的其他示例,请参阅在 Windows Phone 应用程序中实现模型视图查看模型模式

注意注意:

以下过程中的步骤用于 Visual Studio 2010 Express for Windows Phone。 当您使用用于 Visual Studio 2010 Professional 或 Visual Studio 2010 Ultimate 的插件时,您可能会看到菜单命令或窗口布局中的一些微小改变。

在此节中,您将创建应用程序并修改应用程序清单文件,以指定与该应用程序相关的搜索扩展。在此示例中,指定了三个扩展来说明三种类型的快速卡。有关所有扩展的列表,请参阅 Windows Phone 的搜索注册和启动引用

配置应用程序清单

  1. 在 Visual Studio 2010 Express for Windows Phone 中,通过选择“文件 | 新建项目”菜单命令创建一个新项目。

  2. 将显示“新建项目”窗口。展开“Visual C#”模板,然后选择“Silverlight for Windows Phone”模板。

  3. 选择“Windows Phone 应用程序”模板。用您选择的名称填写“名称”框。

  4. 单击“确定”。将显示“新建 Windows Phone 应用程序”窗口。

  5. “Windows Phone 目标版本”菜单中,确保已选择 Windows Phone 7.1。

  6. 单击“确定”。将创建一个新的项目,并且“MainPage.xaml”将在 Visual Studio 设计器窗口中打开。

  7. “解决方案资源管理器”中,展开“属性”,然后双击“WMAppManifest.xml”。这将打开应用程序清单文件。

  8. “WMAppManifest.xml”中,向 App 元素中添加以下代码,放在 Tokens 元素下面。

        <Extensions>
          <!-- Production extensions, for products: video games -->
          <Extension
            ExtensionName="Bing_Products_Video_Games"
            ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}"
            TaskID="_default"
            ExtraFile="Extensions\\Extras.xml" />
    
          <!-- Production extensions, for movies. -->
          <Extension
            ExtensionName="Bing_Movies"
            ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}"
            TaskID="_default"
            ExtraFile="Extensions\\Extras.xml" />
          
          <!-- Production extensions, for places: travel, food, and dining. -->
          <Extension
            ExtensionName="Bing_Places_Food_and_Dining"
            ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}"
            TaskID="_default"
            ExtraFile="Extensions\\Extras.xml" />
        </Extensions>
    
    

    该代码添加三个扩展,每种快速卡类型一个扩展:产品卡、电影卡以及地点卡。与这些扩展不关联的快速卡不会将该应用程序显示在与该快速卡相对应的“应用”Pivot 页面中。有关搜索扩展的完整列表,请参阅 Windows Phone 的搜索注册和启动引用

在本节中,您创建 Extras.xml 文件并指定将出现在对应快速卡的“应用”Pivot 页面中的应用程序标题和说明。

创建 Extras.xml 文件

  1. “解决方案资源管理器”中,右键单击项目,选择“添加”,然后选择“新文件夹”

  2. 将新文件夹命名为 Extensions

  3. “解决方案资源管理器”中,右键单击 Extensions 文件夹,选择“添加”,然后选择“新项”

  4. “添加新项”窗口中,选择“XML 文件”并将该文件命名为 Extras.xml。然后单击“添加”

  5. Extras.xml 中,将代码替换为以下代码。

    <?xml version="1.0" encoding="utf-8" ?>
    <ExtrasInfo>
    
      <!-- Application title -->
      <AppTitle>
        <default>Display App Connect URI Parameters</default>
      </AppTitle>
    
      <!-- Search-related captions -->
      <Consumer ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}">
    
        <!-- Products caption for video games -->
        <ExtensionInfo>
          <Extensions>
            <ExtensionName>Bing_Products_Video_Games</ExtensionName>
          </Extensions>
          <CaptionString>
            <default>Product URI Details</default>
          </CaptionString>
        </ExtensionInfo>
    
        <!-- Movies caption -->
        <ExtensionInfo>
          <Extensions>
            <ExtensionName>Bing_Movies</ExtensionName>
          </Extensions>
          <CaptionString>
            <default>Movie URI Details</default>
          </CaptionString>
        </ExtensionInfo>
    
        <!-- Places caption for food and dining -->
        <ExtensionInfo>
          <Extensions>
            <ExtensionName>Bing_Places_Food_and_Dining</ExtensionName>
          </Extensions>
          <CaptionString>
            <default>Place URI Details</default>
          </CaptionString>
        </ExtensionInfo>
      </Consumer>
    </ExtrasInfo>
    
    

    该代码指定应用程序标题和说明将出现在“应用”Pivot 页面中的方式(具体取决于快速卡类型)。在所有快速卡的应用程序 Pivot 页面中,应用程序标题将为“显示关联的应用 URI 参数”。标题因快速卡类型而异:

    • 对于产品卡(与 Bing_Products_Electronics 扩展关联):“产品 URI 详细信息”

    • 对于电影卡(与 Bing_Movies 扩展关联的快速卡):“电影 URI 详细信息”

    • 对于地点卡(与 Bing_Places_Food_and_Dining 扩展关联):“地点 URI 详细信息”

在本节中,您将 URI 从快速卡深层链接映射到快速卡目标页面中。通过创建快速卡 URI 映射器类并将其分配到 app.xaml.cs 文件中的应用程序框架,可以实现此操作。请注意,快速卡目标页面将在本主题后面的“创建快速卡目标页面”一节中进行创建。

本节中创建的 URI 映射器类通过使用要在您的应用程序中启动的页面名称替换“SearchExtras”来修改 URI。它还对每个 URI 参数值进行重新编码,以便处理可能从快速卡中发送的所有特殊字符。

提示提示:

本主题与快速卡示例相对应。若要下载完整的应用程序(包括名为 QuickCardUriMapper 的 URI 映射器类),请参阅 Windows Phone 的代码示例

创建 URI 映射器类

  1. “解决方案资源管理器”中,右键单击您的项目,选择“添加”,然后选择“新项”

  2. “添加新项”窗口中,选择“类”并将文件命名为 QuickCardUriMapper.cs。然后单击“添加”

  3. QuickCardUriMapper.cs 中,将指令列表替换为以下内容。

    using System;
    using System.Windows.Navigation;
    using System.Net;
    
    
  4. QuickCardUriMapper.cs 中,更新类语句,使其继承自 UriMapperBase 类,如下所示。

    public class QuickCardUriMapper : UriMapperBase
    
    
  5. QuickCardUriMapper 类中,添加以下代码。此代码对每个“关联的应用”URI 参数值进行重新编码。URI 的目标页由名为 TargetPageName 的静态字符串确定。

    // Navigation destination. 
    private static string TargetPageName = "QuickCardTargetPage.xaml";
    private string tempUri;
    
    public override Uri MapUri(Uri uri)
    {
        tempUri = uri.ToString();
                
        // Parse URI when launched by App Connect from Search
        if (tempUri.Contains("/SearchExtras"))
        {
            // Decode all characters in the URI.
            tempUri = HttpUtility.UrlDecode(tempUri);
    
            // Create a new URI for product cards.
            if (tempUri.Contains("Bing_Products"))
            {
                return GetProductCardUri(tempUri);
            }
    
            // Create a new URI for place cards.
            if (tempUri.Contains("Bing_Places"))
            {
                return GetPlaceCardUri(tempUri);
            }
    
            // Create a new URI for movie cards.
            if (tempUri.Contains("Bing_Movies"))
            {
                return GetMovieCardUri(tempUri);
            }
        }
    
        // Immediately return the URI when it is not related to App Connect for Search.
        return uri;
    }
    
    // Return a parsed Product Card URI.
    private Uri GetProductCardUri(string uri)
    {
        // Extract parameter values from URI.
        string ProductNameValue = GetURIParameterValue("ProductName=",uri);
        string CategoryValue = GetURIParameterValue("Category=",uri);
    
        // Create new URI.
        string NewURI = String.Format("/{0}?ProductName={1}&Category={2}", 
                                TargetPageName, ProductNameValue, CategoryValue);
    
        return new Uri(NewURI, UriKind.Relative);
    }
    
            
    // Return a parsed Place Card URI.
    private Uri GetPlaceCardUri(string uri)
    {
        // Extract parameter values from URI.
        string PlaceNameValue = GetURIParameterValue("PlaceName=", uri);
        string PlaceLatitudeValue = GetURIParameterValue("PlaceLatitude=", uri);
        string PlaceLongitudeValue = GetURIParameterValue("PlaceLongitude=", uri);
        string PlaceAddressValue = GetURIParameterValue("PlaceAddress=", uri);
        string CategoryValue = GetURIParameterValue("Category=", uri); 
    
        // Create new URI.
        string NewURI = String.Format("/{0}?PlaceName={1}&PlaceLatitude={2}&PlaceLongitude={3}&PlaceAddress={4}&Category={5}", 
                                TargetPageName, PlaceNameValue, PlaceLatitudeValue, PlaceLongitudeValue, PlaceAddressValue, CategoryValue);
    
        return new Uri(NewURI, UriKind.Relative);       
    }
    
    // Return a parsed Movie Card URI.
    private Uri GetMovieCardUri(string uri)
    {
        // Extract parameter values from URI.
        string MovieNameValue = GetURIParameterValue("MovieName=", uri);
        string CategoryValue = GetURIParameterValue("Category=", uri);
    
        // Create new URI.
        string NewURI = String.Format("/{0}?MovieName={1}&Category={2}",
                    TargetPageName, MovieNameValue, CategoryValue);
    
        return new Uri(NewURI, UriKind.Relative);
    }
    
    
    // This method extracts the string values that correspond to parameters in an App Connect URI.
    private string GetURIParameterValue(string parameteridentifier, string uri)
    {
        string tempValue = "";
    
        // If the parameter exists in the string, extract the corresonding parameter value.
        if (uri.Contains(parameteridentifier))
        {
            string subUri; 
    
            // Extract the characters that contain and follow the parameter identifier.
            subUri = uri.Substring(uri.LastIndexOf(parameteridentifier));
    
            // Remove the parameter identifier from the substring.
            subUri = subUri.Replace(parameteridentifier, "");
                    
            // Obtain the position of the next parameter in the substring.
            int nextParameterPosition = FindNextParameter(subUri);
    
                    
            if (nextParameterPosition < int.MaxValue)
            {
                // Remove the characters that contain and follow the next parameter.
                tempValue = subUri.Substring(0, nextParameterPosition);
            }
            else
            {
                // No more parameters follow in the string. 
                tempValue = subUri;
            }
    
            // Encode the parameter values to help prevent issues in the URI.
            tempValue = HttpUtility.UrlEncode(tempValue);
        }
            
        return tempValue;
    }
    
    // Returns the string position of the next App Connect URI parameter, if applicable.
    private int FindNextParameter(string subUri)
    {
        int lowestPosition = int.MaxValue;
        int tempPosition;
    
        tempPosition = subUri.IndexOf("&ProductName");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&Category");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&PlaceName");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("?PlaceName");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&PlaceLatitude");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&PlaceLongitude");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&PlaceAddress");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        tempPosition = subUri.IndexOf("&MovieName");
        if ((tempPosition > -1) && (tempPosition < lowestPosition)) lowestPosition = tempPosition;
    
        return lowestPosition;
    }
    
    

将 URI 映射器分配到应用程序框架

  • App.xaml.cs 中,向 InitializePhoneApplication 方法中添加以下代码。请注意,您可能需要展开标题为“Phone application initialization”的代码区域来查找此方法。

    // Assign the quick card URI-mapper class to the application frame.
    RootFrame.UriMapper = new QuickCardUriMapper();
    
    

    此代码将 QuickCardUriMapper 类分配到应用程序框架的 UriMapper 属性。请不要修改 InitializePhoneApplication 方法中的任何现有代码;应仅添加 UriMapper 分配,如以下示例中所示。

    private void InitializePhoneApplication()
    {
        if (phoneApplicationInitialized)
            return;
    
        // Create the frame but don't set it as RootVisual yet; this allows the splash
        // screen to remain active until the application is ready to render.
        RootFrame = new PhoneApplicationFrame();
        RootFrame.Navigated += CompleteInitializePhoneApplication;
    
        // Assign the quick card URI-mapper class to the application frame.
        RootFrame.UriMapper = new QuickCardUriMapper();
    
        // Handle navigation failures
        RootFrame.NavigationFailed += RootFrame_NavigationFailed;
    
        // Ensure we don't initialize again
        phoneApplicationInitialized = true;
    }
    

在本节中,您创建在“关联的应用”深层链接 URI 中表示快速卡中参数的数据模型。此类用于绑定到 UI 中的元素。有关与每个快速卡相对应的参数的完整列表,请参阅 Windows Phone 的搜索注册和启动引用

创建数据模型

  1. “解决方案资源管理器”中,右键单击项目,选择“添加”,然后选择“新文件夹”

  2. 将新文件夹命名为 Model

  3. “解决方案资源管理器”中,右键单击 Model 文件夹,选择“添加”,然后选择“新项”

  4. “添加新项”窗口中,选择“代码文件”并将该文件命名为 AppConnectUriParameter.cs。然后单击“添加”

  5. AppConnectUriParameter.cs 中,添加以下代码。

    using System.ComponentModel;
    
    namespace AppConnectExample.Model
    {
        // Represents a parameter from a quick card in an App Connect deep link URI
        public class AppConnectUriParameter : INotifyPropertyChanged
        {
            // The parameter name
            private string _paramName;
            public string ParamName
            {
                get {return _paramName;}
                set
                {
                    if (_paramName != value)
                    {
                        _paramName = value;
                        NotifyPropertyChanged("ParamName");
                    }
                }
            }
    
            // The parameter value
            private string _paramValue;
            public string ParamValue
            {
                get {return _paramValue;}
                set
                {
                    if (_paramValue != value)
                    {
                        _paramValue = value;
                        NotifyPropertyChanged("ParamValue");
                    }
                }
            }
    
            // Class constructor
            public AppConnectUriParameter(string pName, string pValue)
            {
                _paramName = pName.Trim();
    
                if (_paramName == "Category")
                {
                // Place multiple categories on new lines.
                    _paramValue = pValue.Replace(",",",\n");
                }
                else
                {
                    _paramValue = pValue;
                }
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            #endregion
        }
    }
    
    

    此类由参数名称和值、接受名称和值的构造函数以及 INotifyPropertyChanged 成员组成。

在本节中,您创建与快速卡目标页面 QuickCardTargetPage.xaml 相对应的 ViewModel。此 ViewModel 负责从“关联的应用”深层链接中提取 URI 参数。

创建 ViewModel

  1. “解决方案资源管理器”中,右键单击项目,选择“添加”,然后选择“新文件夹”

  2. 将新文件夹命名为 ViewModel

  3. “解决方案资源管理器”中,右键单击 ViewModel 文件夹,选择“添加”,然后选择“新项”

  4. “添加新项”窗口中,选择“代码文件”并将该文件命名为 QuickCardTargetPageViewModel.cs。然后单击“添加”

  5. QuickCardTargetPageViewModel.cs 中,添加以下代码。

    using System.ComponentModel;
    using System.Collections.ObjectModel;
    using System.Collections.Generic;
    
    // Reference the data model.
    using AppConnectExample.Model;
    
    namespace AppConnectExample.ViewModel
    {    
        public class QuickCardTargetPageViewModel: INotifyPropertyChanged
        {
            // Observeable collection for the App Connect deep link URI parameters.
            private ObservableCollection<AppConnectUriParameter> _AppConnectUriParameters;
            public ObservableCollection<AppConnectUriParameter> AppConnectUriParameters
            {
                get {return _AppConnectUriParameters;}
                set
                {
                    if (_AppConnectUriParameters != value)
                    {
                        _AppConnectUriParameters = value;
                        NotifyPropertyChanged("AppConnectUriParameters");
                    }
                }
            }
    
            // Class constructor.
            public QuickCardTargetPageViewModel()
            {
                // Create observeable collection object.
                AppConnectUriParameters = new ObservableCollection<AppConnectUriParameter>();
            }
    
            // Load parameters from quick page; extract from the NavigationContext.QueryString
            public void LoadUriParameters(IDictionary<string,string> QueryString)
            {
                // Clear parameters in the ViewModel.
                AppConnectUriParameters.Clear();
    
                // Loop through the quick card parameters in the App Connect deep link URI.
                foreach (string strKey in QueryString.Keys)
                {
                    // Set default value for parameter if no value is present.
                    string strKeyValue = "<no value present in URI>";
    
                    // Try to extract parameter value from URI.
                    QueryString.TryGetValue(strKey, out strKeyValue);
    
                    // Add parameter object to ViewModel collection.
                    AppConnectUriParameters.Add(new AppConnectUriParameter(strKey, strKeyValue));
                }
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            // Used to notify that a property has changed.
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }
    }
    
    

    LoadUriParameters 方法中,此 ViewModel 从“关联的应用”深层链接 URI 提取参数并将这些参数加载到类型为 AppConnectUriParameter 的可观察集合中。

在本节中,您创建快速卡目标页面。该页面通过“关联的应用”深层链接 URI 从快速卡启动。对于 MVVM 模式,此页面为视图。

创建快速卡目标页面

  1. “解决方案资源管理器”中,右键单击您的项目,选择“添加”,然后选择“新项”

  2. “添加新项”窗口中,选择“Windows Phone 纵向页面”并将该文件命名为 QuickCardTargetPage.xaml。然后单击“添加”

  3. QuickCardTargetPage.xaml 中,将名为 LayoutRoot 的网格替换为以下代码。

        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock 
                    x:Name="ApplicationTitle" 
                    Text="QUICK CARD EXAMPLE" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock 
                    x:Name="PageTitle" 
                    Text="URI details" 
                    Margin="9,-7,0,0" 
                    Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
     
            <!--ContentPanel contains ListBox and ListBox ItemTemplate.-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <ListBox x:Name="paramsListBox" Margin="0,0,-12,0" ItemsSource="{Binding AppConnectUriParameters}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel >
                                <TextBlock 
                                    Text="{Binding ParamName}" 
                                    TextWrapping="Wrap" 
                                    Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                                <TextBlock 
                                    Text="{Binding ParamValue}" 
                                    TextWrapping="Wrap" 
                                    Margin="12,-6,12,0" 
                                    Style="{StaticResource PhoneTextAccentStyle}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </Grid>
        </Grid>
    
    

    在此页面中,一个 ListBox 控件绑定到 ViewModel 中名为 AppConnectUriParameters 的可观察集合。在 ListBox 中,两个 TextBlock 控件绑定到此可观察集合中的每个参数。一个 TextBlock 控件绑定到 ParamName 属性,另一个 TextBlock 控件绑定到 ParamValue 属性。

  4. 在快速卡目标页面的代码隐藏文件 QuickCardTargetPage.xaml.cs 中,向页面顶部添加以下指令。

    // Reference the ViewModel.
    using AppConnectExample.ViewModel;
    
    
  5. QuickCardTargetPage.xaml.cs 中,将以下代码添加到类构造函数中的 InitializeComponent() 调用后面。

                // Create the ViewModel object.
                this.DataContext = new QuickCardTargetPageViewModel();
    
                // Create event handler for the page Loaded event.
                this.Loaded += new RoutedEventHandler(QuickCardTargetPage_Loaded);
    
    
    

    该代码创建新的 QuickCardTargetPageViewModel 对象并将该对象分配给页面的数据上下文。该代码还为页面 Loaded 事件创建事件处理程序。

  6. QuickCardTargetPage.xaml.cs 中,向页面类中添加以下代码。

            // A property for the ViewModel.
            QuickCardTargetPageViewModel ViewModel
            {
                get { return (QuickCardTargetPageViewModel)DataContext; }
            }
    
    
            private void QuickCardTargetPage_Loaded(object sender, RoutedEventArgs e)
            {
                // Load the quick card parameters from the App Connect deep link URI.
                ViewModel.LoadUriParameters(this.NavigationContext.QueryString);
            }
    
    

    该代码创建 ViewModel 的一个属性以便可以调用 LoadUriParameters 方法。在页面 Loaded 事件的处理程序中,NavigationContext QueryString 属性传递给 ViewModel 以便可以从“关联的应用”深层链接 URI 中提取参数。

在本节中,您向主页中添加文本以便用于标准应用程序启动。

完成应用程序

  • 在应用程序的主页 MainPage.xaml 中,将名为 LayoutRoot 的网格替换为以下代码。

        <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock 
                    x:Name="ApplicationTitle" 
                    Text="QUICK CARD EXAMPLE" 
                    Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock 
                    x:Name="PageTitle" 
                    Text="main page" 
                    Margin="9,-7,0,0" 
                    Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - place additional content here-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="24,0,42,338">
                <TextBlock 
                    Text="With App Connect, you can navigate directly to a relevant page in your app from a Bing quick card."
                    TextWrapping="Wrap"  
                    Style="{StaticResource PhoneTextAccentStyle}" 
                    Margin="0,0,12,181" />
    
                <TextBlock Text="To launch this app from a quick card, perform the testing steps outlined in the documentation."
                    TextWrapping="Wrap" 
                    Style="{StaticResource PhoneTextAccentStyle}" 
                    Margin="0,94,0,83" />
            </Grid>
        </Grid>
    
    

    该代码完成该应用程序的构建。

该应用程序设计为帮助您浏览活动的快速卡。在本节中,您搜索与应用程序清单文件中配置的扩展关联的产品、电影和地点。找到某个快速卡之后,您启动您的应用程序以查看从“关联的应用”深层链接 URI 传递到您的应用程序的参数。

从快速卡启动该应用程序将中断调试连接。若要调试您的应用程序,请按照名为调试应用程序的过程执行操作。

重要说明重要说明:

使用快速卡测试您的应用程序需要您 PC 或 Windows Phone 设备的 Internet 连接。

使用产品卡进行测试

  1. 按 F5 可调试您的应用程序并将其部署到模拟器或设备。

  2. 该应用程序加载后,点按硬件“搜索”按键以打开 Bing。

  3. 在 Bing 中,输入与视频游戏产品有关的搜索条件(如视频游戏控制台名称)。例如,“xbox 360”将返回与 Xbox 360 控制台有关的产品卡。若要使用 Bing_Products_Video_Games 扩展测试产品卡,需要注意两件事:

    • Bing 必须考虑与视频游戏产品有关的搜索条件。

    • 与搜索条件有关的产品卡必须在 Bing 上存在并且与 Bing_Products_Video_Games 扩展关联。

  4. Web Pivot 页面上,在“产品”标题下选择一个产品。这将启动与产品有关的快速卡。

    提示提示:

    如果您没有看到“产品”标题,则尝试其他搜索条件或向 WMAppManifest.xmlExtras.xml 文件中添加另一个产品扩展。有关搜索扩展的完整列表,请参阅 Windows Phone 的搜索注册和启动引用

  5. 在产品的快速卡上,滑过“应用”Pivot 页面并点按标题为“显示 URI 参数”的应用程序。请注意,说明的内容为“产品 URI 详细信息”

    注意注意:

    如果您没有看到“应用”Pivot 页面,则没有特定的产品卡与 WMAppManifest.xmlExtras.xml 文件中列出的产品扩展相关联。点按“返回”按键并尝试其他产品卡。

  6. “应用”Pivot 页面中点按该应用程序之后,观察到 QuickCardTargetPage.xaml 页面显示该产品“关联的应用”深层链接 URI 中的参数。

使用电影卡进行测试

  1. 按 F5 可调试您的应用程序并将其部署到模拟器或设备。如果您已经部署了该应用程序,则此步骤是可选的。

  2. 该应用程序加载后,点按硬件“搜索”按键以打开 Bing。

  3. 在 Bing 中,输入与电影院当前正在放映的电影相关的搜索条件,如“电影”“电影院放映的影片”或您所在位置附近正在放映的电影名称。若要使用 Bing_Movies 扩展测试电影卡,需要注意两件事:

    • Bing 必须考虑与电影院当前正在放映的电影相关的搜索条件。

    • 与搜索条件有关的电影卡必须在 Bing 上存在并且与 Bing_Movies 扩展关联。

  4. Web Pivot 页面上,选择在 Web 标题上面的搜索结果中列出的电影。这将启动与电影有关的快速卡。

    注意注意:

    如果您没有看到 Web 标题上面列出的电影,则尝试其他搜索条件。没有可用于电影的其他扩展。

  5. 在电影的快速卡上,滑过“应用”Pivot 页面并点按标题为“显示 URI 参数”的应用程序。请注意,标题的内容为“电影 URI 详细信息”

  6. “应用”Pivot 页面中点按该应用程序之后,观察到 QuickCardTargetPage.xaml 页面显示该电影“关联的应用”深层链接 URI 中的参数。

使用地点卡进行测试

  1. 按 F5 可调试您的应用程序并将其部署到模拟器或设备。

  2. 该应用程序加载后,点按硬件“搜索”按键以打开 Bing。

  3. 在 Bing 中,输入与餐饮有关的搜索条件,如“饮食”或您附近餐馆的名称。若要使用 Bing_Places_Food_and_Dining 扩展测试地点卡,需要注意两件事:

    • Bing 必须考虑与餐饮位置有关的搜索条件。

    • 与搜索条件有关的地点卡必须在 Bing 上存在并且与 Bing_Places_Food_and_Dining 扩展关联。

  4. “本地”Pivot 页面中,选择其下显示地图的餐饮位置。这将启动与地点有关的快速卡。

    提示提示:

    如果您没有在“本地”Pivot 页面上看到结果,则尝试其他搜索条件或向 WMAppManifest.xmlExtras.xml 文件中添加另一个地点扩展。有关搜索扩展的完整列表,请参阅 Windows Phone 的搜索注册和启动引用

  5. 在地点的快速卡上,滑过“应用”Pivot 页面并点按标题为“显示 URI 参数”的应用程序。请注意,标题的内容为“地点 URI 详细信息”

    注意注意:

    如果您没有看到“应用”Pivot 页面,则没有特定的地点卡与 WMAppManifest.xmlExtras.xml 文件中列出的地点扩展相关联。点按“返回”按键并尝试其他地点卡。

  6. “应用”Pivot 页面中点按该应用程序之后,观察到 QuickCardTargetPage.xaml 页面显示该地点“关联的应用”深层链接 URI 中的参数。

当应用程序从某个快速卡重新启动时中断调试过程。若要调试您应用程序的“关联的应用”启动,您需要模拟一个深层链接 URI。为此,执行以下过程以临时替换 WPAppManifest.xml 文件中的 DefaultTask 元素。

调试应用程序

  1. 在应用程序清单文件 WPAppManifest.xml 中,临时注释原始的 DefaultTask 元素。

    重要说明重要说明:

    注释掉 DefaultTask 元素可以防止您的应用程序执行到主页的标准启动;完成调试后取消注释该元素,这一点很重要。

  2. WPAppManifest.xml 中,向 Tasks 元素中添加以下临时 DefaultTask 元素。

    <DefaultTask Name="_default" NavigationPage="SearchExtras?MovieName=Test&amp;Category=Bing_Movies" />
    

    DefaultTask 元素模拟名为“Test”的电影的电影卡。

  3. 按 F5 可调试您的应用程序并将其部署到模拟器或设备。

  4. 观察到该应用程序直接启动到 QuickCardTargetPage.xaml 页面并且显示名为 Test 的电影的“关联的应用”深层链接 URI 中的参数。

  5. WPAppManifest.xml 中,注释掉临时的 DefaultTask 元素并取消注释原始元素。完成后,Tasks 元素应类似于以下代码。

    <Tasks>
      <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
      <!--<DefaultTask  Name="_default" NavigationPage="SearchExtras?MovieName=Test&amp;Category=Bing_Movies" />-->
    </Tasks>
    

显示: