Synster
Synster

Reputation: 339

Combobox IsTextSearchEnabled = True validating entered text to check if it is present in Itemsource

I have a very simple use case using ComboBox where IsTextSearchEnabled property is true i.e. user can enter his text but I want to check if the entered text is present in the itemsource.

Is there a simple way to this than binding Text property and validating entered text?

Upvotes: 1

Views: 4833

Answers (1)

SamTh3D3v
SamTh3D3v

Reputation: 9944

I believe yes, this is the easiest way to do it, but this may not be very mvvm friendly, so basically what you need to do is :

  1. Set the Combobox's IsTextSearchEnabled and IsEditable to true,
  2. Bind the Combobox's Text Property to a String property in your codebehind,
  3. each time the user enters text in the combobox, two possible senarios might occurs: either the entered text is in the ItemSource, in that case no further treatment is needed, the second possible scenario is that the entered text does't exist in the ItemSource, in that case you need to rollback and delete the last entered caracter,

here the xaml :

<Window ...
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <ComboBox IsTextSearchEnabled="True" TextSearch.TextPath="Name" x:Name="cbx"  ItemsSource="{Binding Items}" IsEditable="True" DisplayMemberPath="Name"  Text="{Binding AddedText,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"></ComboBox>        
</Grid>

and here the properties and Model that needs to be added to the codebehind

 public class ListIte
 {
    public String Name { get; set; }        
 }
 //...
 private ObservableCollection<ListIte> _items =new ObservableCollection<ListIte>()
    {
        new ListIte()
        {
            Name = "Name"
        }, new ListIte()
        {
            Name = "Element"
        }, new ListIte()
        {
            Name = "Save"
        }, new ListIte()
        {
            Name = "Test"
        },
    } ;
    public ObservableCollection<ListIte> Items
    {
        get
        {
            return _items;
        }

        set
        {
            if (_items == value)
            {
                return;
            }

            _items = value;
            OnPropertyChanged();
        }
    }

    private String _addedText ="" ;

    public String AddedText
    {
        get
        {
            return _addedText;
        }

        set
        {
            if (_addedText == value)
            {
                return;
            }
            if (Items.FirstOrDefault(x => x.Name.StartsWith(value))==null)
            {   
                //to get the Editable TextBox from the combobox
                var textBox = cbx.Template.FindName("PART_EditableTextBox", cbx) as TextBox;
                textBox.Text = textBox.Text.Substring(0, textBox.Text.Length - 1);
                textBox.CaretIndex = textBox.Text.Length;
                return;
            }

            _addedText = value;
            OnPropertyChanged();
        }
    }

Upvotes: 2

Related Questions