@@ -145,57 +145,68 @@ public void UnregisterEvents()
145145
146146 private void OnAutoSuggestBox_QuerySubmitted ( AutoSuggestBox sender , AutoSuggestBoxQuerySubmittedEventArgs args )
147147 {
148- if ( args . ChosenSuggestion != null )
148+ if ( args . ChosenSuggestion != null && args . ChosenSuggestion is DataItem infoDataItem )
149149 {
150- if ( args . ChosenSuggestion is DataItem )
150+ var hasChangedSelection = EnsureItemIsVisibleInNavigation ( infoDataItem . Title ) ;
151+
152+ // In case the menu selection has changed, it means that it has triggered
153+ // the selection changed event, that will navigate to the page already
154+ if ( ! hasChangedSelection )
151155 {
152- var infoDataItem = args . ChosenSuggestion as DataItem ;
153156 NavigateTo ( infoDataItem . UniqueId , infoDataItem ) ;
154157 }
155158 }
156159 }
157160
158161 private void OnAutoSuggestBox_TextChanged ( AutoSuggestBox sender , AutoSuggestBoxTextChangedEventArgs args )
159162 {
160- var matches = SearchNavigationViewItems ( DataSource . Instance . Groups . SelectMany ( group => group . Items ) , sender . Text ) ;
161-
162- if ( matches . Any ( ) )
163+ if ( args . Reason == AutoSuggestionBoxTextChangeReason . UserInput )
163164 {
164- foreach ( var item in matches )
165+ var suggestions = new List < DataItem > ( ) ;
166+
167+ var querySplit = sender . Text . Split ( " " ) ;
168+ foreach ( var group in DataSource . Instance . Groups )
165169 {
166- if ( string . IsNullOrEmpty ( item . ImagePath ) )
170+ var matchingItems = group . Items . Where (
171+ item =>
172+ {
173+ // Idea: check for every word entered (separated by space) if it is in the name,
174+ // e.g. for query "split button" the only result should "SplitButton" since its the only query to contain "split" and "button"
175+ // If any of the sub tokens is not in the string, we ignore the item. So the search gets more precise with more words
176+ bool flag = item . IncludedInBuild ;
177+ foreach ( string queryToken in querySplit )
178+ {
179+ // Check if token is not in string
180+ if ( item . Title . IndexOf ( queryToken , StringComparison . CurrentCultureIgnoreCase ) < 0 )
181+ {
182+ // Token is not in string, so we ignore this item.
183+ flag = false ;
184+ }
185+ }
186+ return flag ;
187+ } ) ;
188+ foreach ( var item in matchingItems )
167189 {
168- item . ImagePath = _autoSuggestBoxNotFoundImagePath ;
190+ if ( string . IsNullOrEmpty ( item . ImagePath ) )
191+ {
192+ item . ImagePath = _autoSuggestBoxNotFoundImagePath ;
193+ }
194+ suggestions . Add ( item ) ;
169195 }
170196 }
171- _autoSuggestBox . ItemsSource = matches . OrderByDescending ( i => i . Title . StartsWith ( sender . Text . ToLowerInvariant ( ) ) ) . ThenBy ( i => i . Title ) ;
172- }
173- else
174- {
175- var noResultsItem = new DataItem ( ) ;
176- noResultsItem . Title = _autoSuggestBoxNotFoundString ;
177- noResultsItem . ImagePath = _autoSuggestBoxNotFoundImagePath ;
178-
179- var noResultsList = new List < DataItem > ( ) ;
180- noResultsList . Add ( noResultsItem ) ;
181- _autoSuggestBox . ItemsSource = noResultsList ;
182- }
183- }
184-
185- public IEnumerable < DataItem > SearchNavigationViewItems ( IEnumerable < DataItem > items , string query )
186- {
187- if ( string . IsNullOrWhiteSpace ( query ) )
188- yield break ;
189-
190- query = query . Trim ( ) ;
191-
192- foreach ( var item in items )
193- {
194- if ( ! string . IsNullOrEmpty ( item . Title )
195- && item . Title . Contains ( query , StringComparison . OrdinalIgnoreCase )
196- && item . UniqueId != null )
197+ if ( suggestions . Count > 0 )
197198 {
198- yield return item ;
199+ _autoSuggestBox . ItemsSource = suggestions . OrderByDescending ( i => i . Title . StartsWith ( sender . Text , StringComparison . CurrentCultureIgnoreCase ) ) . ThenBy ( i => i . Title ) ;
200+ }
201+ else
202+ {
203+ var noResultsItem = new DataItem ( ) ;
204+ noResultsItem . Title = _autoSuggestBoxNotFoundString ;
205+ noResultsItem . ImagePath = _autoSuggestBoxNotFoundImagePath ;
206+
207+ var noResultsList = new List < DataItem > ( ) ;
208+ noResultsList . Add ( noResultsItem ) ;
209+ _autoSuggestBox . ItemsSource = noResultsList ;
199210 }
200211 }
201212 }
@@ -257,4 +268,71 @@ private bool EnsureNavigationSelectionBase(object rawItem, string id, Navigation
257268 }
258269 return false ;
259270 }
271+
272+ public bool EnsureItemIsVisibleInNavigation ( string name )
273+ {
274+ bool changedSelection = false ;
275+ foreach ( object rawItem in this . AllMenuItems )
276+ {
277+ // Check if we encountered the separator
278+ if ( ! ( rawItem is NavigationViewItem ) )
279+ {
280+ // Skipping this item
281+ continue ;
282+ }
283+
284+ var item = rawItem as NavigationViewItem ;
285+
286+ // Check if we are this category
287+ if ( ( string ) item . Content == name )
288+ {
289+ _navigationView . SelectedItem = item ;
290+ changedSelection = true ;
291+ }
292+ // We are not :/
293+ else
294+ {
295+ // Maybe one of our items is?
296+ if ( item . MenuItems . Count != 0 )
297+ {
298+ foreach ( NavigationViewItem child in item . MenuItems )
299+ {
300+ if ( ( string ) child . Content == name )
301+ {
302+ // We are the item corresponding to the selected one, update selection!
303+
304+ // Deal with differences in displaymodes
305+ if ( _navigationView . PaneDisplayMode == NavigationViewPaneDisplayMode . Top )
306+ {
307+ // In Topmode, the child is not visible, so set parent as selected
308+ // Everything else does not work unfortunately
309+ _navigationView . SelectedItem = item ;
310+ item . StartBringIntoView ( ) ;
311+ }
312+ else
313+ {
314+ // Expand so we animate
315+ item . IsExpanded = true ;
316+ // Ensure parent is expanded so we actually show the selection indicator
317+ _navigationView . UpdateLayout ( ) ;
318+ // Set selected item
319+ _navigationView . SelectedItem = child ;
320+ child . StartBringIntoView ( ) ;
321+ }
322+ // Set to true to also skip out of outer for loop
323+ changedSelection = true ;
324+ // Break out of child iteration for loop
325+ break ;
326+ }
327+ }
328+ }
329+ }
330+ // We updated selection, break here!
331+ if ( changedSelection )
332+ {
333+ break ;
334+ }
335+ }
336+ return changedSelection ;
337+ }
260338}
0 commit comments