Search code examples
c#uwp-xamlwinui-3

NavigationView and AutoSuggestbox not suggesting NavigationViewItems UWP


I've stuck on the problem with matching phrases with Property value "Content" of NavigationViewItem. My app is pretty large, so I made a sample view for the sake of this post.

This is my XAML View Code

<Page
    x:Class="testowa.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:testowa"
    xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:rg="using:SourceChord.ResponsiveGrid"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">

    <Page.Resources>
        <!--This top margin is the height of the custom TitleBar-->
        <Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>

    </Page.Resources>
    <Grid>
        <Border x:Name="AppTitleBar"
                IsHitTestVisible="True"
                VerticalAlignment="Top"
                Background="Transparent"
                Height="40"
                Canvas.ZIndex="1" 
                Margin="48,8,0,0">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="AppFontIcon"
                    HorizontalAlignment="Left" 
                    VerticalAlignment="Center"
                    Source="Assets/Square44x44Logo.png" 
                    Width="16" 
                    Height="16"/>
                <TextBlock x:Name="AppTitle"
                    Text="Aplikacja Szpitalna"
                    VerticalAlignment="Center"
                    Margin="12, 0, 0, 0"
                    Style="{StaticResource CaptionTextBlockStyle}" />
            </StackPanel>
        </Border>
        <muxc:NavigationView x:Name="NavigationViewControl"
            IsTitleBarAutoPaddingEnabled="False"            
            IsBackButtonVisible="Visible"           
            DisplayModeChanged="NavigationViewControl_DisplayModeChanged"   
            Canvas.ZIndex="0">
            <muxc:NavigationView.Header>
                <Grid HorizontalAlignment="Left" Padding="0" Margin="6,0,0,0">
                    <TextBlock Text="Dashboard" HorizontalAlignment="Center" FontSize="20" />
                </Grid>
            </muxc:NavigationView.Header>
            <muxc:NavigationView.AutoSuggestBox>
                <AutoSuggestBox 
                    PlaceholderText="Wyszukaj" 
                    QueryIcon="Find"                     
                    x:Name="controlsSearchBox"
                    TextChanged="ControlsSearchBox_TextChanged"
                    VerticalAlignment="Center"
                    x:FieldModifier="public"
                    MinWidth="200"
                    KeyboardAcceleratorPlacementMode="Hidden">
                </AutoSuggestBox>
            </muxc:NavigationView.AutoSuggestBox>
            <muxc:NavigationView.MenuItems>
                <muxc:NavigationViewItemSeparator />
                <muxc:NavigationViewItem Icon="Home" Content="Menu Główne"/>
                <muxc:NavigationViewItemSeparator />
                <!--Sekcja techniczna-->
                <muxc:NavigationViewItemHeader Content="Techniczne" Margin="0,20,0,0"/>
                <muxc:NavigationViewItem Icon="List" Content="System Kolejkowy"/>

                <muxc:NavigationViewItem Icon="FourBars" Content="Networking">
                    <muxc:NavigationViewItem.MenuItems>
                        <muxc:NavigationViewItem Content="Serwery" Icon="AllApps"/>
                        <muxc:NavigationViewItem Content="Urządzenia aktywne" Icon="Manage"/>
                        <muxc:NavigationViewItem Content="Punkty PPD" Icon="Map"/>
                        <muxc:NavigationViewItem Content="Adresy IP" Icon="GoToStart"/>
                        <muxc:NavigationViewItem Content="Dostęp zdalny" Icon="Globe"/>
                        <muxc:NavigationViewItem Content="Skaner ARP" Icon="Find"/>
                    </muxc:NavigationViewItem.MenuItems>
                </muxc:NavigationViewItem>
            </muxc:NavigationView.MenuItems>
        </muxc:NavigationView>
    </Grid>
</Page>

This is Event Method binded to AutoSuggestBox

private void ControlsSearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
    // Pobierz tekst z elementu AutoSuggestBox
    string searchText = sender.Text;

    // Filtruj elementy menu nawigacyjnego za pomocą pobranego tekstu
    var filteredMenuItems = NavigationViewControl.MenuItems
        .OfType<NavigationViewItem>()
        .Where(item => item.Content.ToString().ToLowerInvariant().Contains(searchText.ToLowerInvariant()))
        .ToList();

    // Ustaw wynik filtrowania jako elementy sugestii dla elementu AutoSuggestBox
    sender.ItemsSource = filteredMenuItems;
}

Nothing happens, Debug.WriteLine shows 0 elements in filteredMenuItems. I've been looking the solution for days. Checked Learn.Microsoft, sample Github projects.

I'm expecting the code shows NavigationViewItems which match the phrase with Content


Solution

  • There are not only NavigationViewItem in the NavigationViewControl.MenuItems, but also NavigationViewItemSeparator and NavigationViewItemHeader in it.

    Please try the following code:

        public List<string> CheckItems( List<object> sourceList, List<string> resultList, string searchText) 
        {
            foreach (var item in sourceList)
            {
                if (item.GetType() == typeof(MUXC.NavigationViewItem))
                {
                    // get first level item
                    MUXC.NavigationViewItem viewItem = item as MUXC.NavigationViewItem;
    
                    //check if contains second level items
    
                    List<object> level2Items = viewItem.MenuItems.ToList();
    
                    if (level2Items.Count > 0)
                    {
                        CheckItems(level2Items,resultList,searchText);
                    }
                    else
                    {
                        // this is the first level item
                        var str = viewItem.Content.ToString().ToLowerInvariant();
                        if (str.Contains(searchText))
                        {
                            resultList.Add(viewItem.Content.ToString());
                        }
                    }
                }
            }
    
            return resultList;
        }
    
        private void controlsSearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
        {
            string searchText = sender.Text;
    
            List<string> resultList = new List<string>();
    
            List<object> itemlist = NavigationViewControl.MenuItems.ToList();
    
            CheckItems(itemlist, resultList, searchText);
    
            sender.ItemsSource = resultList;
        }