Click here to Skip to main content
15,881,877 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm using C# WPF I have Combobox in my project and that will fill items from database

my Combobox IsEditable is true it means users can type instead choosing item from list

the problem is they can enter invalid item something else its not in list of combobox

without error

I found this solution :

private void cmb_LostFocus(object sender, RoutedEventArgs e)
        {
            bool allowed = false;
            foreach (ComboBoxItem it in cmb.Items)
            {
                if (it.Content.ToString() == cmb.Text)
                {
                    allowed = true;
                    break;
                }
            }
            if (!allowed)
            {
                lblmessages.Content = "Invalid Items";
            }
            else
            {
                lblmessages.Content = "";
            }
        }



but that is not good solution for big list of combobox if i had a list of cites of countries that should check the text item by item that will be slow

so in other language i saw "NotInList" this option prevent to type anything else in not in list combobox

I didn't see this in WPF

How can i prevent to enter invalid item in combobox with allowing type text and choosing item

Please Help me

What I have tried:

private void cmb_LostFocus(object sender, RoutedEventArgs e)
        {
            bool allowed = false;
            foreach (ComboBoxItem it in cmb.Items)
            {
                if (it.Content.ToString() == cmb.Text)
                {
                    allowed = true;
                    break;
                }
            }
            if (!allowed)
            {
                lblmessages.Content = "Invalid Items";
            }
            else
            {
                lblmessages.Content = "";
            }
        }
Posted
Updated 31-Jul-21 12:15pm
Comments
[no name] 7-Dec-20 3:03am    
The number of countries is not "a lot". If you have a "backing collection" for your CB, you can easily check that using LINQ.
CHill60 8-Dec-20 11:57am    
How are you populating the combobox values?
#realJSOP 11-Dec-20 10:18am    
Maybe a combo box isn't the best control choice here.

1 solution

To check if a value is inside a collection or not, you will always need to perform some check. In this case, you need a collection that can check for a unique value very fast. What you need is a HashSet<string> collection, which uses binary search. For example:

C#
// This is initialized on demand (lazy). It is also not case-sensitive.
// Culture is important here; we are using Ordinal comparison, but you may wish 
// to change this to current culture or invariant culture, depending on your purpose.
private readonly var _comboItems = new Lazy<HashSet<string>>(
    () => new HashSet<string>(StringComparer.OrdinalIgnoreCase));


Then, use this collection in a property and provide it as the ItemsSource of the ComboBox. Like this:

C#
public ISet<string> ComboItems => _comboItems.Value;


XML
<ComboBox ItemsSource="{Binding ComboItems}"/>


You would populate the items collection from the database by using the property.
C#
// This adds an item to the HashSet. If the item already exists, it will be ignored.
ComboItems.Add(myDatabaseItem);


Remember that, because HashSet doesn't provide notification events, WPF doesn't know when the collection is changed, so you need to populate the collection before the ComboBox is instantiated, or you need to re-set ItemsSource property again, by setting it to null and then to ComboItems again. If you want to decouple your C# code from XAML objects (recommended), you can instead access the CollectionView for your collection and request that it is updated. Like the following:

C#
// This will access the collection view wrapping ComboItems and refresh it.
// Do this only after updating items on the ComboItems collection.
var collectionView = CollectionViewSource.GetDefaultView(ComboItems);  // This can return null.
collectionView?.Refresh();


When you need to determine if a specific item exists on the ComboItems collection, you would need just the following code:
C#
// Determine if the text entered by the user is one of the items on our collection.
// Remember, our collection is performing case-insensitive comparisons.
// Also, remember that the user can enter blank spaces or be deleting text, generating a TextChanged event.
string textToCheck = "Item you want to check";  // This is the text entered by the user.
if (string.IsNullOrWhiteSpace(texToCheck))
{
    // The user entered blank spaces or deleted the whole string, so there is no error here.
}
else if (ComboItems.Contains(textToCheck.Trim()))
{
    // The user entered a valid item that exists on the collection. Do something here.
}
else
{
    // The user entered an item that doesn't exist on the collection. Do something here.
}
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900