Search code examples
c#mvvmuwptemplate10

AutoSuggestBox with Template10 doesn't suggest anything


I'm currently learning programming in C# and XAML and also using the MVVM. I have checked the official AutoSuggestBox sample from Microsoft. I looked at the code and tried to achieve the same thing with Template 10 but with no luck. No suggestions pop up.

MainPage.XML:

<AutoSuggestBox RelativePanel.Below="stateTextBox"
                x:Name="asb"
                PlaceholderText="Type a name (e.g. John)"
                DisplayMemberPath="DisplayName"
                TextMemberPath="DisplayName"
                QueryIcon="Find"
                Margin="0,24,0,24"
                MinWidth="296"
                HorizontalAlignment="Left"
                TextChanged="{x:Bind ViewModel.FilterUsuals}"
                QuerySubmitted="{x:Bind ViewModel.ProcessQuery}"
                SuggestionChosen="{x:Bind ViewModel.ProcessChoice}"
                ItemsSource="{Binding Elements}"
                />

MainPageViewModel.cs:

Contact _Contact = default(Contact);
public Contact Contact { get { return _Contact; } set { Set(ref _Contact, value); } }

public void FilterUsuals(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
    // We only want to get results when it was a user typing,
    // otherwise we assume the value got filled in by TextMemberPath
    // or the handler for SuggestionChosen
    if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
    {
        var matchingContacts = ContactSampleDataSource.GetMatchingContacts(sender.Text);

        sender.ItemsSource = matchingContacts.ToList();
    }
}

public void ProcessQuery(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
    if (args.ChosenSuggestion != null)
    {
    }
    else
    {
    }
}

public void ProcessChoice(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
    var contact = (Contact)args.SelectedItem;
}

Solution

  • I'd suggest handling UI events in your page's code-behind in order to keep the UI separate from the view-model.

    Here's an example, with some extras removed to keep it simple:

    MainPage.xaml:

    <AutoSuggestBox x:Name="FruitsSuggestion"
                    ItemsSource="{x:Bind ViewModel.FruitSuggestions, Mode=OneWay}"                    PlaceholderText="Search"
                    QueryIcon="Find"
                    QuerySubmitted="FruitsSuggestion_QuerySubmitted"
                    Text="{x:Bind ViewModel.Query, Mode=TwoWay}" />
    

    MainPage.xaml.cs:

    private void FruitsSuggestion_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
    {
        ViewModel.Filter();
    }
    

    MainPageViewModel.cs:

    private string _query = default(string);
    public string Query { get => _query; set => Set(ref _query, value); }
    
    private List<string> _allFruits = new List<string>
    {
        "Apple",
        "Banana",
        "Orange",
        "Plum",
        "Peach",
        "Pineapple"
    };
    private ObservableCollection<string> _fruitSuggestions = new ObservableCollection<string>();
    public ObservableCollection<string> FruitSuggestions => _fruitSuggestions;
    
    public void Filter()
    {
        FruitSuggestions.Clear();
        FruitSuggestions.AddRange(from fruit in _allFruits
                                  where fruit.Contains(Query)
                                  select fruit);
    }
    

    When you run the Filter method, it will update the ObservableCollection, which will in turn update the suggested items in your AutoSuggestBox.