RadAutoCompleBox with custom search function

5 posts, 0 answers
  1. Guy
    Guy avatar
    21 posts
    Member since:
    Oct 2012

    Posted 22 Nov 2012 Link to this post

    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?
  2. Guy
    Guy avatar
    21 posts
    Member since:
    Oct 2012

    Posted 23 Nov 2012 Link to this post

    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.

  3. Daniel
    Daniel avatar
    28 posts
    Member since:
    Jul 2018

    Posted 22 Nov 2018 in reply to Guy Link to this post

    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.
  4. Daniel
    Daniel avatar
    28 posts
    Member since:
    Jul 2018

    Posted 22 Nov 2018 in reply to Guy Link to this post

    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.

     

     

     

  5. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2240 posts

    Posted 27 Nov 2018 Link to this post

    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.
Back to Top