WPF ComboBox с IsEditable = "True" - Как я могу указать, что совпадений не найдено? - PullRequest
6 голосов
/ 06 января 2011

Используя в качестве примера следующее простое текстовое поле:

<ComboBox IsEditable="True" SelectedItem="{Binding}">
    <ComboBoxItem>Angus/ComboBoxItem>
    <ComboBoxItem>Jane</ComboBoxItem>
    <ComboBoxItem>Steve</ComboBoxItem>
</ComboBox>

Я бы хотел, чтобы пользователь мог найти свой выбор, введя имя, поэтому я установил IsEditable равно истине.Приемлемыми значениями для свойства, связанного с SelectedItem , является любой из параметров в списке или отсутствие выбора ( null ).Проблема в том, что по умолчанию отсутствует индикация ошибки, если кто-то вводит имя, которого нет в списке.

Например: пользователь может ввести «Боб», вызывая SelectedItem свойство должно иметь значение null , но не понимать, что Боб не существует в списке.Вместо этого я хотел бы предоставить визуальную индикацию, как только свойство Text ComboBox не будет null или пустым И SelectedItem равно null ,и не позволять им больше печатать?

Моей первоначальной мыслью было пользовательское правило проверки, но я не знаю, как получить доступ к свойствам Text и SelectedItem в выпадающем списке.

Ответы [ 3 ]

3 голосов
/ 06 января 2011

Для начала вы можете захотеть, чтобы пользователь увидел, вводит ли он один из доступных вариантов.

1) Поиск "combocomboox автозаполнения" онлайн.

2) Проверкаэто из:

http://weblogs.asp.net/okloeten/archive/2007/11/12/5088649.aspx

http://www.codeproject.com/KB/WPF/WPFCustomComboBox.aspx

3) Также попробуйте это:

    <ComboBox IsEditable="true" TextSearch.TextPath="Content">
        <ComboBoxItem Content="Hello"/>
        <ComboBoxItem Content="World"/>
    </ComboBox>

Приведенный выше фрагмент кода является простым способомпредоставить ту «визуальную индикацию», которую вы ищете.Если пользователь вводит «h», тогда «hello» появится в текстовом поле ввода.Однако это само по себе не будет иметь механизма, который не позволит пользователю вводить недопустимый символ.

4) Это более продвинутая версия:

    <ComboBox Name="myComboBox" IsEditable="true" KeyUp="myComboBox_KeyUp">
        <ComboBoxItem Content="Hello"/>
        <ComboBoxItem Content="World"/>
        <ComboBoxItem Content="WPF"/>
        <ComboBoxItem Content="ComboBox"/>
    </ComboBox>

Code-behind:

    private void myComboBox_KeyUp(object sender, KeyEventArgs e)
    {
        // Get the textbox part of the combobox
        TextBox textBox = myComboBox.Template.FindName("PART_EditableTextBox", myComboBox) as TextBox;

        // holds the list of combobox items as strings
        List<String> items = new List<String>();

        // indicates whether the new character added should be removed
        bool shouldRemove = true;

        for (int i = 0; i < myComboBox.Items.Count; i++)
        {
            items.Add(((ComboBoxItem)myComboBox.Items.GetItemAt(i)).Content.ToString());
        }

        for (int i = 0; i < items.Count; i++)
        {
            // legal character input
            if(textBox.Text != "" && items.ElementAt(i).StartsWith(textBox.Text))
            {
                shouldRemove = false;
                break;
            }
        }

        // illegal character input
        if (textBox.Text != "" && shouldRemove)
        {
            textBox.Text = textBox.Text.Remove(textBox.Text.Length - 1);
            textBox.CaretIndex = textBox.Text.Length;
        }
    }

Здесь мы не разрешаем пользователю продолжать вводить данные, как только мы обнаруживаем, что элемент комбинированного списка не начинается с текста в текстовом поле.Мы удаляем добавленного персонажа и ждем другого персонажа.

2 голосов
/ 04 мая 2015

Это решение основано на ответе пользователя 1234567, с парой изменений. Вместо поиска в списке элементов он просто проверяет SelectedIndex ComboBox на значение> = 0, чтобы увидеть, найдено ли совпадение, и это решает проблему RB о удерживании клавиши, вставляющей более одного символа. Он также добавляет звуковую обратную связь при отклонении символов.

private int _lastMatchLength = 0;

private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
    _lastMatchLength = 0;
}

private void myComboBox_KeyUp(object sender, KeyEventArgs e)
{
    ComboBox cBox = sender as ComboBox;

    TextBox tb = cBox.Template.FindName("PART_EditableTextBox", cBox) as TextBox;
    if (tb != null)
    {
        if (cBox.SelectedIndex >= 0)
        {
            _lastMatchLength = tb.SelectionStart;
        }
        else if (tb.Text.Length == 0)
        {
            _lastMatchLength = 0;
        }
        else
        {
            System.Media.SystemSounds.Beep.Play();
            tb.Text = tb.Text.Substring(0, _lastMatchLength);
            tb.CaretIndex = tb.Text.Length;
        }
    }
}
1 голос
/ 03 мая 2012

Это хорошее решение, пока в поле со списком не будет много записей.Я бы сделал это следующим образом:

Объявите это в верхней части файла

List<String> items = new List<String>(); 

private void myComboBox_KeyUp(object sender, KeyEventArgs e) 
{ 
  TextBox textBox = myComboBox.Template.FindName("PART_EditableTextBox", myComboBox) as TextBox; 

     // indicates whether the new character added should be removed 
    bool shouldRemove = true; 

    // this way you don't fill the list for every char typed
    if(items.Count <= 0)
    { 
       for (int i = 0; i < myComboBox.Items.Count; i++) 
       { 
           items.Add(((ComboBoxItem)myComboBox.Items.GetItemAt(i)).Content.ToString()); 
       } 
    }
    // then look in the list
    for (int i = 0; i < items.Count; i++) 
    { 
        // legal character input 
        if(textBox.Text != "" && items.ElementAt(i).StartsWith(textBox.Text)) 
        { 
            shouldRemove = false; 
            break; 
        } 
    } 

    // illegal character input 
    if (textBox.Text != "" && shouldRemove) 
    { 
        textBox.Text = textBox.Text.Remove(textBox.Text.Length - 1); 
        textBox.CaretIndex = textBox.Text.Length; 
    } 
} 

, если только привязка не будет продолжать добавлять записи в поле со списком, я думаю, это более эффективный поиск1006 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...