Skip to content

SearchBox is a pill-shaped search trigger that opens a flyout with a query editor, a result list and an Open button. The control does not filter anything by itself: it raises QueryChanged, and your code fills Results.

Basic usage ​

xml
<dev:SearchBox x:Name="Search"
               Width="260"
               MenuItemInvoked="Search_MenuItemInvoked"
               PlaceholderText="Search"
               QueryChanged="Search_QueryChanged"
               ResultInvoked="Search_ResultInvoked" />
csharp
Search.Results.Add(new SearchResultItem
{
    Title = "Italy 2026 Itinerary",
    Subtitle = "25 minutes ago • Word",
    Glyph = "\uE8A5",
    IconBrush = new SolidColorBrush(Microsoft.UI.ColorHelper.FromArgb(255, 43, 87, 154)),
    Details = new List<SearchBoxDetailRow>
    {
        new("Location", @"C:\Users\Casey\Documents"),
        new("Author", "Casey Jensen")
    }
});

private void Search_QueryChanged(object sender, SearchEventArgs e)
{
    Search.Results.Clear();

    foreach (var item in _all.Where(i => i.Title.Contains(e.Query, StringComparison.OrdinalIgnoreCase)))
    {
        Search.Results.Add(item);
    }
}

private void Search_ResultInvoked(object sender, SearchResultEventArgs e)
{
    StatusText.Text = e.Item != null ? $"Opened: {e.Item.Title}" : $"Search: {e.Query}";
}

Properties ​

PropertyTypeDefaultDescription
PlaceholderTextstring"Search"Text shown on the trigger button and as the editor placeholder.
QueryTextstring""Current query. Setting it updates the editor.
ShowPreviousSearchboolfalseKeeps the query when the flyout closes. When false, the query is cleared and QueryChanged is raised with an empty string.
FlyoutWidthdouble640Width of the flyout content.
ResultsMaxHeightdouble560Maximum height of the result list.
ConstrainToAppBoundsboolfalseKeeps the flyout and item menus inside the app window.
FlyoutPlacementFlyoutPlacementModeBottomFlyout placement. Auto opens below the trigger when there is room, otherwise above.
ItemTemplateDataTemplatebuilt-in templateTemplate used for each result.
NoResultsTextstring"No results found"Title shown when the query has no results.
NoResultsDescriptionstring"Try a different search term"Description shown under the no-results title.
ResultsObservableCollection<SearchResultItem>emptyItems shown in the list.
DefaultMenuItemsObservableCollection<SearchMenuItem>emptyMenu used by the More button for items that have no MenuItems of their own.

Events ​

EventArgumentsRaised when
QueryChangedSearchEventArgs (Query)The query text changes, or the query is cleared on close.
ResultInvokedSearchResultEventArgs (Item, Query)A result is opened by Enter, double tap, the Open button or the item's open action. Item is null when nothing is selected, so you can treat it as a plain search for Query.
MenuItemInvokedSearchMenuItemEventArgs (Item, MenuItem)A command in an item's More menu is clicked.

The flyout closes after ResultInvoked.

Methods ​

MethodDescription
Show()Opens the flyout.
Hide()Closes the flyout.

Result items ​

SearchResultItem ​

PropertyTypeDescription
TitlestringPrimary text. Also used as the accessible name of the row.
SubtitlestringSecondary text.
GlyphstringIcon glyph. Defaults to "\uE8A5".
IconBrushBrush?Icon color. When null, the accent text color is used.
PreviewImageSource?Image shown in the details panel of the selected item.
DetailsIList<SearchBoxDetailRow>Name and value rows shown in the details panel of the selected item.
MenuItemsIList<SearchMenuItem>Item-specific More menu. Falls back to DefaultMenuItems when empty.
Payloadobject?Your own data attached to the item.
IsSelectedboolSelection state, maintained by the control.

The details panel is shown only for the selected item, and only when it has a Preview or at least one detail row.

SearchBoxDetailRow ​

csharp
new SearchBoxDetailRow("File Size", "812 KB")

SearchMenuItem ​

PropertyTypeDescription
TextstringCommand text.
Glyphstring?Optional icon glyph.
Tagobject?Identifier you can check in MenuItemInvoked.
IsSeparatorboolRenders a separator instead of a command.
ActionAction<SearchResultItem>?Callback run before MenuItemInvoked is raised.
csharp
Search.DefaultMenuItems.Add(new SearchMenuItem { Text = "Open", Glyph = "\uE8E5", Tag = "open" });
Search.DefaultMenuItems.Add(new SearchMenuItem { IsSeparator = true });
Search.DefaultMenuItems.Add(new SearchMenuItem { Text = "Remove from list", Glyph = "\uE74D", Tag = "remove" });

private void Search_MenuItemInvoked(object sender, SearchMenuItemEventArgs e)
{
    if (e.MenuItem.Tag as string == "remove")
    {
        _all.Remove(e.Item);
        Refill(Search.QueryText);
    }
}

Keyboard ​

KeyAction
Down / UpMoves the selection through the results.
EnterOpens the selected result, or raises ResultInvoked with a null item when nothing is selected.
EscapeCloses the flyout.

Customization ​

Custom item template ​

ItemTemplate replaces the built-in row. The More and Open buttons of the default template are part of that template, so a custom template provides its own actions.

xml
<dev:SearchBox ItemTemplate="{StaticResource MyResultTemplate}" />

Text resources ​

Button texts are resources, so they can be changed or localized without code.

KeyDefaultUsed for
SearchBoxOpenButtonTextOpenThe Open button in the flyout.
SearchBoxItemMoreTextMore optionsName and tooltip of the More button on a row.
SearchBoxItemOpenTextOpenName and tooltip of the Open button on a row.

Define the same key in a dictionary closer to the control than the library defaults, such as a page or parent element Resources. A definition in App.xaml may not take priority over the library's own dictionary.

Style resources ​

Sizing, spacing and corner radii are resources and can be overridden the same way.

KeyDefault
SearchBoxTriggerCornerRadius18
SearchBoxFlyoutCornerRadius16
SearchBoxEditorCornerRadius12
SearchBoxItemCornerRadius8
SearchBoxOpenButtonCornerRadius8
SearchBoxDetailsCornerRadius8
SearchBoxTriggerPadding14,0
SearchBoxFlyoutPadding8
SearchBoxItemMargin0,0,0,2
SearchBoxItemPadding12,8
SearchBoxDetailsMargin12,0,12,8
SearchBoxDetailsPadding16,12
SearchBoxNoResultsPadding24,40
SearchBoxTriggerMinHeight36
SearchBoxTriggerMinWidth200
SearchBoxTriggerIconSize14
SearchBoxEditorHeight96
SearchBoxItemIconSize22
SearchBoxItemActionSize32
SearchBoxPreviewMaxHeight190
SearchBoxSelectedItemBackgroundBrushControlSolidFillColorDefaultBrush (highlight in high contrast)

Template parts ​

A custom ControlTemplate for SearchBox should provide these named parts.

PartType
PART_TriggerButtonButton with a Flyout
PART_SearchTextBoxTextBox
PART_ResultsListListView
PART_OpenButtonButton
PART_NoResultsPresenterFrameworkElement

Accessibility ​

  • The editor takes its accessible name from PlaceholderText.
  • The More and Open buttons on each row have accessible names and tooltips.
  • Rows are announced by Title.
  • The no-results message is a polite live region.

NOTE

  • Fill Results from QueryChanged; the control never filters on its own.
  • Reuse the same SearchResultItem instances when refilling, so selection state stays consistent.
  • The query is cleared on close unless ShowPreviousSearch is true, and QueryChanged is raised for that clear.

Demo ​

you can run demo and see this feature.

SearchBox

Released under the MIT License.