Integrieren des Search Charm in eine Windows Store App

Von Rina Ahmed Autor Feed 16. April 2013 12:29

Windows 8 bietet dem Benutzer in der Charms Bar eine Möglichkeit, sowohl das System als auch Apps über den Search Charm zu durchsuchen. Wenn du in deiner App dem Benutzer ermöglichen willst, nach Content zu suchen, so ist es empfehlenswert dies über die Charms Bar zu ermöglichen, Dies gewährleistet einerseits, dass der Benutzer eine einheitliche User Experience über das ganze System hinweg hat, andererseits bedeutet es für dich, als Developer, dass deine App häufiger verwendet werden kann, wenn der Benutzer deine App gezielt aufgelistet bekommt, wenn er nach relevantem Content sucht.

Wir wollen nun wie im vorigen Beispiel anhand des RSS Reader Framework von atwork veranschaulichen, wie wir Suche in diese App integrieren können. Wir wollen im wesentlichen drei Dinge implementieren:

  1. Suche während die App läuft
  2. Einbindung von Suggestions beim Eintippen des Suchbegriffs
  3. Starten der App durch externe Suche

Vorbereitung:

Ladet und entpackt das RSS Reader Framework von atwork und öffnet die FeedReaderApp.sln Datei. (Vorraussetzung: ihr habt bereits Visual Studio installiert).

 

Suche im laufenden Zustand der App

  1. Im Solution Explorer klickt ihr mit der rechten Maustaste und wählt Add > New Item… und fügt dann einen Search Contract namens SearchResultsPage.xaml hinzu.

    image

    Öffnet die neu erstellte SearchResultsPage.xaml und sucht Euch in dem Abschnitt <Page.Resources> den String mit dem Key AppName und fügt einen passenden Titel für diese Seite. Wir wählen einfach das Wort Suche als Titel.

     <x:String x:Key="AppName">Suche</x:String>

  2. Sucht Euch das Element namens resultsGridView und fügt unter den Attribute ItemClick=”OnItemClick” hinzu. Dieses Attribut fügt ihr auch in dem Element resultsListView hinzu. in der resultsGridView sieht das jetzt so aus:

    image

  3. Öffnet jetzt die Datei SearchResultsPage.xaml.cs und fügt folgende Methode hinzu:

            private void OnItemClick(object sender, ItemClickEventArgs e)
            {
                // Navigate to the page showing the FeedItem that was clicked
                this.Frame.Navigate(typeof(ItemDetailPage), ((FeedItem)e.ClickedItem).UniqueId);
            }

  4. Ihr müsst ganz oben in dieser Datei noch den Namespaces hinzufügen.

    using FeedReaderApp.Model;
    using FeedReaderApp.DataModel;

  5. Dann fügt Ihr folgende Variable direkt oberhalb dem SearchResultsPage() Konstruktor.

    // Collection of FeedItems representing search results
    private Dictionary<string, List<FeedItem>> _results = new Dictionary<string, List<FeedItem>>();

    Diese Variable wird unsere Ergebnisse enthalten, die mit dem Suchbegriff übereinstimmen.

  6. Sucht euch jetzt in der LoadState Methode den Kommentar Communicate results through the view model. Direkt oberhalb dieses Kommentares fügt ihr folgenden Code ein:

                // Search FeedItems and tabulate results
                var feedItems = FeedsDataSource.Instance.FeedItems; 
     
                string query = queryText.ToLower();
                var all = new List<FeedItem>();
                _results.Add("All", all);
     
                var groupsQ = from item in feedItems                            
                                group item by item.FeedName                            
                                into g
                                select new FeedGrouping()
                                           {
                                               Name = g.Key,
                                               FeedItems = g.ToList()
                                           };
     
                 var groups = groupsQ.ToList();
     
                foreach (var group in groups)
                {
                    var items = new List<FeedItem>();
                    _results.Add(group.Name, items);
     
                    foreach (var item in group.FeedItems)
                    {
                        if (item.Title.ToLower().Contains(query) || 
                              item.Summary.ToLower().Contains(query))
                        {
                            all.Add(item);
                            items.Add(item);
                        }
                    }
     
                    filterList.Add(new Filter(group.Name, items.Count, false));
                }
     
                filterList[0].Count = all.Count;

    Hier holen wir uns alle Blogs mit ihren FeedItems in die Liste namens groups und iterieren über alle FeedItems jedes Blogs, ob der Titel oder die Summary des FeedItems den Suchbegriff enthält. In diesem Fall wird das FeedItems einmal in den Ergebnissen der Kategorie All hinzugefügt und einmal in der Ergebnisliste für den jeweiligen Blog. Das ganze hilft uns nachher die Suchergebnisse nach Blogs zu filtern.

  7. Als nächstes suchen wir uns den Kommentar //TODO: Respond to the change in active filter in der Filter_SelectionChanged Methode. Direkt unter diesem Kommentar fügen wir folgenden Code ein:

    this.DefaultViewModel["Results"] = _results[selectedFilter.Name]; 

  8. Nun wollen wir noch das Aussehen unserer Ergebnisse in unserer SearchResultsPage definieren. Wir erstellen uns hierbei ein DataTemplate, in dem wir festlegen, dass Unsere Ergebnisse in einer Box mit bläulichem Hintergrund angezeigt werden sollen. Wechselt dazu in die Datei SearchResultsPage.xaml und fügt direkt unter dem String AppName unter dem Page.Resources Element (siehe Punkt 1) folgendes DataTemplate ein:

            <DataTemplate x:Key="ErgebnisTemplate">
                <Grid Background="DarkSlateGray" Width="294" Height="115" >               
                    <StackPanel  Grid.Column="1" Margin="6">
                        <TextBlock Text="{Binding Title}" 
                                   Style="{StaticResource BodyTextStyle}" 
                                   TextWrapping="NoWrap"/>
                        <TextBlock Text="{Binding FeedName}" 
                                   Style="{StaticResource BodyTextStyle}" 
                                   Foreground=
                                   "{StaticResource ApplicationSecondaryForegroundThemeBrush}" 
                                   TextWrapping="NoWrap"/>
                        </StackPanel>
                </Grid>
            </DataTemplate>

  9. Dieses DataTemplate wollen wir nun in unseren Ergebnissteuerelementen verwenden. Wir suchen uns das resultsGridView und das resultsListViewElement und geben bei beiden im ItemTemplate Attribut den Namen unseres DataTemplates, das heißt ErgebnisTemplate. Das Ganze sieht im resultsGridView so aus:

    image

  10. Wenn ihr jetzt die Taste F5 betätigt, wird Eure App kompiliert und gestartet. Ihr könnt jetzt über die Charms Bar einen Suchbegriff eingeben und seht dann die Ergebnisse für Euren Suchbegriff.

 

Einbindung von Vorschlägen während der Eingabe

Wir wollen nun einige Stichworte einfügen, die als Vorschlag angezeigt werden, während der Benutzer ähnliche Suchbegriffe eingibt.

  1. Als erstes benötigen wir einen Handler, der ausgeführt wird, wenn der Benutzer Suchbegriffe eingibt. Wechselt hierzu in die Datei App.xaml.cs und fügt folgenden Namespace ganz oben in der Datei hinzu:

    using Windows.ApplicationModel.Search;

  2. Wir gehen nun in die OnLaunched Methode und fügen direkt unter dem Statement CommonInitialize() folgenden Code hinzu, um unseren Handler zu registrieren.

    // Register handler for SuggestionsRequested events from the search pane
     SearchPane.GetForCurrentView().SuggestionsRequested += OnSuggestionsRequested;

  3. Als letzten Schritt fügen wir noch diese Methode in die Klasse ein:

            void OnSuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args)
            {
                string query = args.QueryText.ToLower();
                string[] terms = { "Azure", "apps", "Microsoft", "Windows 8", "Windows",
                                  "Windows Phone"};
     
                foreach (var term in terms)
                {
                    string lTerm = term.ToLower();
                    if (lTerm.StartsWith(query))
                        args.Request.SearchSuggestionCollection.AppendQuerySuggestion(term);
                }
            }

    Ihr könnt dabei andere Begriffe, die Ihr für Eure Feeds als relevant erachtet, in das terms Array eintragen.
    Ihr könnt nun mittels F5 die App starten und solltet bei der Eingabe von Begriffen, die wie eure terms Stichworte beginnen, Vorschläge unter dem Eingabefeld sehen.


    Starten der App durch externe Suche

    Im letzten Teil wollen wir es noch ermöglichen, dass der Benutzer einen Suchbegriff an unsere App weitergibt, während die App nicht im laufenden Zustand ist.

    Als ihr die SearchResultsPage in das Projekt hinzugefügt habt, wurde von Visual Studio automatisch auch eine Methode namens OnSearchActivated in Eurer App.xaml.cs Datei hinzugefügt. Diese Methode wird aufgerufen, wenn der Benutzer einen Suchbegriff in den Search Charm eingibt und Eure App aus der Liste auswählt. Da die App jetzt über OnSearchActivated statt über OnLaunched gestarted wird, müssen wir sicherstellen, dass unsere Initialisierungen für die App auch in der OnSearchActivated Methode vorgenommen werden.

    1. Geht zu der OnSearchActivated Methode in App.xaml.cs und fügt folgenden Code gleich am Beginn in der Methode ein:

       // Reinitialize the app if a new instance was launched for search
                  if (args.PreviousExecutionState == ApplicationExecutionState.NotRunning ||
                      args.PreviousExecutionState == ApplicationExecutionState.ClosedByUser ||
                      args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                  {
                      CommonInitialize();
                      FeedsDataSource.Instance.LoadFeedsParallel(false, false);                
                      // Register handler for SuggestionsRequested events from the search pane
                      SearchPane.GetForCurrentView().SuggestionsRequested += OnSuggestionsRequested;
                  }

    2. Zum Abschluss wollen wir noch einen kleinen Hack einfügen, der nur ganz spezifisch für dieses Projekt relevant ist. Unsere LoadFeedsParallel Methode ladet unsere Feeds, das ganze läuft aber asynchron. Wir brauchen nun einen Hack, damit das Laden alle Feeds abgewartet wird, bevor wir den Suchbegriff mit unseren FeedItems in der SearchResultsPage vergleichen können.
      Öffnet im Solution Explorer im Ordner DataModel die Datei FeedsDataSource.cs und sucht die LoadsFeedParallel Methode. Als erstes wollen wir die Parameter Liste der Methode ändern. Ändert die Signatur der Methode, sodass sie folgende Parameter akzeptiert:

      public bool LoadFeedsParallel(bool refreshMode = false, bool callAsync = true)

      Über dem Statement Debug.WriteLine("LoadFeedsParallel::Started feed tasks"); ziemlich weit unten in der Methode fügen wir diesen Code hinzu:

      // if we load synchron, wait for completion
                  if(!callAsync){
                     do{
                        new System.Threading.ManualResetEvent(false).WaitOne(100);
                     } while(_outstandingFeeds > 0);
                  }

      Nun kompiliert und schließt ihr die App. Wenn ihr nun einen Suchbegriff in der Search Bar eingebt und die FeedReader App aus der App Liste auswählt, so solltet ihr direkt zu der Search Results Page mit den Ergebnissen kommen.

    Pingbacks and trackbacks (1)+

    Add comment

      Country flag

    biuquote
    • Comment
    • Preview
    Loading

    Datenschutzhinweis: Sie stimmen durch "Kommentar speichern" der Speicherung Ihrer Angaben durch Microsoft Österreich für die Beantwortung der Anfrage zu. Sie erhalten dadurch keine unerwünschten Werbezusendungen. Ihre Emailadresse wird auf Ihren Wunsch dazu verwendet Sie über neue Kommentare zu informieren.

    Microsoft respektiert den Datenschutz. Datenschutz & Cookies

    Aktuelle Downloads

    Azure Free Trial
     
    Visual Studio Downloads
     
    Windows Azure Free Trial

     
      Developer Events
    Instagram
    CodeFest.at on Facebook

    Datenschutz & Cookies · Nutzungsbedingungen · Impressum · Markenzeichen
    © 2013 Microsoft. Alle Rechte vorbehalten · BlogEngine.NET 2.7.0.0 · Diese Website wird für Microsoft von atwork gehostet.
    powered by atwork