This is a migrated thread and some comments may be shown as answers.

RadAutoCompleBox with custom search function

4 Answers 359 Views
AutoCompleteBox
This is a migrated thread and some comments may be shown as answers.
Guy
Top achievements
Rank 2
Guy asked on 22 Nov 2012, 11:47 AM
Hi

I have a requirement from my users to be able to type into an autocompletebox and have it suggest results based on multiple values from my business object.

As an example, if the business object looks like this:
public class Client
{
    public string Name {get;set;}
    public string AccountCode {get;set;}
    public string Address {get;set;}
}

I want to be able to tell RadAutoCompleteBox to not only search on the Name field, but also the AccountCode when the user types into the box. The item data template I am showing the user is a stack panel containing both fields, so then they can start typing a value from either field to populate the suggestion box.

If I could provide the control with a search function to use instead of TextSearchPath, that would be ideal. A lamba like this would do the trick:

radacbox.SearchFunction += (client, search_text) => { client.Name.Contains(search_text) || client.AccountCode.Contains(search_text) };

Is there any way to override the default search behavior of the RadAutoCompleteBox?

4 Answers, 1 is accepted

Sort by
0
Guy
Top achievements
Rank 2
answered on 23 Nov 2012, 07:24 AM
Ok, for anyone trying to do this, I solved my own problem. RadAutoCompleteBox has a FilterBehavior member which is based on the IFilteringBehavior interface. Simply create a class which implements that interface, like this:

internal class CustomRadAutoCompleteBehavior : IFilteringBehavior
    {
        internal CustomRadAutoCompleteBehavior()
        {
             // custom setup code
        }
 
        public IEnumerable<object> FindMatchingItems(string searchText, System.Collections.IList items, IEnumerable<object> escapedItems, string textSearchPath, TextSearchMode textSearchMode)
        {
            // custom filtering code returning IEnumerable of objects to display
        }
    }

and set your RadAutoCompleteBox's FilterBehavior to an instance of the new class, like this:

radBox.FilteringBehavior = new CustomRadAutoCompleteBehavior();

There you go, now you can filter the autocomplete items however you want, not just on a single string member.

0
Daniel
Top achievements
Rank 1
answered on 22 Nov 2018, 03:28 PM
Interesting, I think I will try using this to implement my own search.  I was looking to do "StartsWith" if the user enters 1-2 characters since it's kind of useless to do contains but once the user reaches 3 characters I want to switch to "Contains".  I'll post back if I get it working.
0
Daniel
Top achievements
Rank 1
answered on 22 Nov 2018, 04:08 PM

Took me a little while to figure out how to query the IList but after some research into reflection I got it working on the first try which is crazy (for me anyway).

Here's the class

 internal class CustomRadAutoCompleteBehavior : IFilteringBehavior
    {
        public IEnumerable<object> FindMatchingItems(string searchText, IList items, IEnumerable<object> escapedItems, string textSearchPath, TextSearchMode textSearchMode)
        {
            var itemsToReturn = new List<object>();

            int itemCount = (int)items.GetType().GetProperty("Count").GetValue(items, null);
            for (int i = 0; i < itemCount; i++)
            {
                object[] index = { i };
                object item = items.GetType().GetProperty("Item").GetValue(items, index);
                PropertyInfo[] itemProperties = item.GetType().GetProperties();

                foreach (PropertyInfo property in itemProperties)
                {
                    if(property.Name == textSearchPath)
                    {
                        var propertyValue = property.GetValue(item, null).ToString();
                        if (searchText?.Length < 3)
                        {
                            if(propertyValue.StartsWith(searchText))
                            {
                                itemsToReturn.Add(item);
                            }
                        }
                        else
                        {
                            if(propertyValue.Contains(searchText))
                            {
                                itemsToReturn.Add(item);
                            }
                        }
                    }
                }
            }

            return itemsToReturn;
        }
    }

 

Basically I have to get a count of the items using reflection, then loop through those items.  I then get all the properties of each item and loop through until I get the property matching the textSearchPath (which is the property you are filtering on).  I then check the searchText to see if it's under 3 characters and use the StartsWith if it is and Contains if it isn't.  If either of these conditions are met I add them to my list of objects to return to the filter.  It works awesome.

 

To attach the behaviour to the control you just add a key to your resources section:

<behaviors:CustomRadAutoCompleteBehavior x:Key="CustomAutoCompleteFiler" />

Then on the auto complete you add FilteringBehavior="{StaticResource CustomAutoCompleteFiler}"

And that's it.

 

 

 

0
Martin Ivanov
Telerik team
answered on 27 Nov 2018, 10:58 AM
Hi Daniel,

That's nice. Thank you for sharing your solution here. I am sure that it will be helpful for the other forum members.

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
AutoCompleteBox
Asked by
Guy
Top achievements
Rank 2
Answers by
Guy
Top achievements
Rank 2
Daniel
Top achievements
Rank 1
Martin Ivanov
Telerik team
Share this question
or