如何使AutoSuggestBox只允许从ItemsSource中选择“已接受”的文本?

时间:2018-05-06 14:58:09

标签: c# uwp

我正在尝试阻止C#/ UWP AutoSuggestionBox从提交的搜索中找到未在ItemsSource列表中找到的Box中的文本。如果找不到搜索,我希望无法从AutoSuggestionBox中删除输入焦点,直到通过从ItemsSource列表中选择有效条目,或通过自动选择列表中最接近的匹配或用户来更正问题单击“x”清除搜索。只有在这些条件匹配之前,才允许从AutoSuggestionBox中删除焦点。

这是我想要的效果。这是来自Access数据库的ComboBox的剪辑:

Combobox with autocompletion

请注意,它会自动选择列表中最接近的匹配项,并滚动到该列表,并使用匹配项完成光标后的文本...

关于如何使用AutoSuggestionBox执行此操作或类似操作的任何想法?

1 个答案:

答案 0 :(得分:0)

Alternative Solution,Popup用于创建类似功能的对话框。 XAML如下:

<ContentDialog ...
    x:Class="MyApp1.ContentDialog1"
    x:Name="A1Dialog"
    Title="MyDialog"
    DefaultButton="Primary"
    PrimaryButtonText="Ok"
    SecondaryButtonText="Cancel"
    Loaded="ContentDialog_Loaded"
    PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
    SecondaryButtonClick="ContentDialog_SecondaryButtonClick">

<Grid Name="A1Grid" 
      Height="{Binding ElementName=A1Dialog, Path=ActualHeight}">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <TextBox Name="A1TextBox" Grid.Row="0" 
         PlaceholderText="Search String" 
         TextChanged="A1TextBox_TextChanged"/>

    <ScrollViewer Grid.Row="1"
       ScrollViewer.VerticalScrollBarVisibility="Auto"
       VerticalAlignment="Stretch">
        <ListBox Name="A1ListBox" MinHeight="200"/>
    </ScrollViewer>

    </Grid>
</ContentDialog>

C#按如下方式支持XAML:

using System;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Collections.Generic;

public sealed partial class ContentDialog1 : ContentDialog
{
    List<string> Choices = new List<string>
    {
            "One", "Two", "Three", "Four",
            "Five", "Six", "Seven", "Eight",
            "Nine", "Ten", "Eleven", "Twelve",
            "13", "14", "15", "16",
            "17", "18", "19",
            "20"
    };

    public ContentDialog1()
    {
        this.InitializeComponent();
        A1ListBox.ItemsSource = Choices;
        this.IsPrimaryButtonEnabled = false;
    }

    private void A1TextBox_TextChanged(
        object sender, 
        TextChangedEventArgs e)
    {
        this.IsPrimaryButtonEnabled = false;
        string text = A1TextBox.Text;
        if (string.IsNullOrEmpty(text))
        {
            A1ListBox.ItemsSource = Choices;
        }
        else
        {
            string search = text.ToLower();
            List<string> list = Choices.Where(
                    x => x.ToLower().Contains(search))
                    .ToList();

            A1ListBox.ItemsSource = list;
            if (list.Count != 0)
            {
                this.IsPrimaryButtonEnabled = true;
                A1ListBox.SelectedIndex = 0;
            }
        }

    }

    // OK Button
    private void ContentDialog_PrimaryButtonClick(
         ContentDialog sender, 
         ContentDialogButtonClickEventArgs args)
    {
    }

    // Cancel Button
    private void ContentDialog_SecondaryButtonClick(
          ContentDialog sender, 
          ContentDialogButtonClickEventArgs args)
    {
    }

    private void ContentDialog_Loaded(object sender, RoutedEventArgs e)
    {
    }

}

从方法打开DialogBox:

async void Click(sender s, …) {
    var D = new ContentDialog1();
    ContentDialogResult Result = await D.ShowAsync();
    switch(Result) {
        // Ok Button
        case ContentDialogResult.Primary:
            // this might require a little bit of fixing
            // to save result in public variable...
            // because A1ListBox is not public visible...
            // but the idea is similar...
            var SelectedItem = D.A1ListBox.SelectedItem;
            DoSomethingOk();
            break;
        // Cancel Button
        case ContentDialogResult.Seconday:
            DoSomethingCancel();
            break;
    }
}