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

DropDownList custom autocomplete

7 Answers 175 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Aleksandr
Top achievements
Rank 1
Aleksandr asked on 10 Jun 2014, 10:06 AM
Hello!
I'm using RadDropDownList control in DropDown and SuggestAppend mode. I have a databound collection of customers (simple object with properties Id, Name, Phone, Email etc).

I've figured out how to implement "contains" search with:
ddlCustomers.DropDownListElement.AutoCompleteSuggest.SuggestMode = SuggestMode.Contains;

But now I need to search not only by customer Name, but by Phone too (and maybe by Email in the future).
I think that I need to implement my own suggest helper and inherit it from AutoCompleteSuggestHelper.
Am I right? If so, which methods should I override? Or maybe there is more simple solution here?
Thank you in advance.

7 Answers, 1 is accepted

Sort by
0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 13 Jun 2014, 07:49 AM
Hello Aleksandr,

Thank you for writing.

Here is a sample implementation of a custom AutoCompleteSuggestHelper. Overriding the DefaultFilter method gives you the option to achieve custom logic for filtering by two or more fields.

As to the SyncItemsCore method, it is used only to assign the DataBoundItem to the auto-complete item's Tag property, which will be used for access to fields different than the DisplayMember/ValueMember:
public Form1()
{
    InitializeComponent();
 
    this.radDropDownList1.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown;
    this.radDropDownList1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
    this.radDropDownList1.DropDownListElement.AutoCompleteSuggest.SuggestMode = SuggestMode.Contains;
}
 
private void Form1_Load(object sender, EventArgs e)
{
    this.customersTableAdapter.Fill(this.nwindDataSet.Customers);
    this.radDropDownList1.DataSource = this.customersBindingSource;
    this.radDropDownList1.DisplayMember = "ContactName";
    this.radDropDownList1.ValueMember = "CustomerID";
}
 
public class CustomDropDownList : RadDropDownList
{
    public override string ThemeClassName 
    {
        get
        {
            return typeof(RadDropDownList).FullName; 
        }
    }
 
    protected override RadDropDownListElement CreateDropDownListElement()
    {
        return new CustomDropDownListElement();
    }
}
 
public class CustomDropDownListElement : RadDropDownListElement
{
    protected override Type ThemeEffectiveType    
    {
        get   
        {
            return typeof(RadDropDownListElement);    
        }
    }
 
    protected override AutoCompleteSuggestHelper CreateAutoCompleteSuggestHelper()
    {
        return new CustomAutoCompleteSuggestHelper(this);
    }
}
 
public class CustomAutoCompleteSuggestHelper : AutoCompleteSuggestHelper
{
    public CustomAutoCompleteSuggestHelper(RadDropDownListElement owner) : base(owner)
    {
    }
 
    protected override bool DefaultFilter(RadListDataItem item)
    {
        DataRowView rowView = item.Tag as DataRowView;
        if (rowView != null)
        {
            DataRow curtomerRow = rowView.Row;
            string customerAdrress = curtomerRow["Address"].ToString();
            return item.Text.ToLower().StartsWith(this.Filter.ToLower()) &&
                   customerAdrress.ToLower().Contains(this.Filter.ToLower());
        }
 
        return base.DefaultFilter(item);
    }
 
    protected override void SyncItemsCore()
    {
        this.DropDownList.ListElement.Items.Clear();
        this.DropDownList.ListElement.BeginUpdate();
        foreach (RadListDataItem item in Owner.Items)
        {
            RadListDataItem newItem = new RadListDataItem(item.Text);
            newItem.Tag = item;
            newItem.Value = item.Value;
            newItem.TextWrap = item.TextWrap;
            newItem.Enabled = item.Enabled;
            newItem.Tag = item.DataBoundItem;
            this.DropDownList.ListElement.Items.Add(newItem);
        }
 
        this.DropDownList.ListElement.EndUpdate();
    }
 
    public override void AutoComplete(KeyPressEventArgs e)
    {
        base.AutoComplete(e);
        if (this.DropDownList.Items.Count > 0)
        {
            this.DropDownList.SelectedIndex = this.DropDownList.FindString(this.Filter);
        }
    }
}

Note that this is just an example and it may not cover all possible cases. Feel free to modify it on a way, which suits your requirement best.

I hope this information helps. Should you have further questions, I would be glad to help.

Regards,
Desislava
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Aleksandr
Top achievements
Rank 1
answered on 16 Jun 2014, 09:34 AM
Thank you! This worked for me.
0
Fariba
Top achievements
Rank 1
answered on 16 Jan 2018, 08:32 AM

Hi

I am using a RadDropDownList and bounding the dataSourde .

DisplayMember is the combination of 2 columns. // DisplayMember= Firstcol+" ["+SecondCol+"]"

I need the shown datas of  the AutoCompleteSuggestHelper’s pop-up has a special custom filter

first contains of first column, then contains of the second column (of displaymember)

So I inherited CustomAutoCompleteSuggestHelper of AutoCompleteSuggestHelper and overide DefaultFilter

protected override bool DefaultFilter(RadListDataItem item)

        {
            this.DropDownList.SortStyle = Telerik.WinControls.Enumerations.SortStyle.None;

            var newlist = item.Text.Split('[');
            return ((newlist[0].ToLower().Contains(this.Filter.ToLower())) || newlist[1].ToLower().Contains(this.Filter.ToLower()));
               
        }

and assigned this class to my dropdown

mydropdown.DropDownListElement.AutoCompleteSuggest = new CustomAutoCompleteSuggestHelper(cmbInstruments.DropDownListElement);

 

it works , but the problem is the DropDownList.SortStyle is changed.

For some reason I want it in none style mode  ,but by raising DefaultFilter it changed to Ascending mode

 

StackTrace:

Telerik.WinControls.UI.dll!Telerik.WinControls.UI.AutoCompleteSuggestHelper.ApplyFilterToDropDown(string filter)

 Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadListElement.SetSortStyle(Telerik.WinControls.Enumerations.SortStyle value)

Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadListElement.OnSortStyleChanged(Telerik.WinControls.Enumerations.SortStyle sortStyle) 

 

What should I do?

0
Fariba
Top achievements
Rank 1
answered on 16 Jan 2018, 08:34 AM
Hi
I am using a RadDropDownList and bounding the dataSourde .
DisplayMember is the combination of 2 columns. // DisplayMember= Firstcol+" ["+SecondCol+"]"
I need the shown datas of  the AutoCompleteSuggestHelper’s pop-up has a special custom filter
first contains of first column, then contains of the second column (of displaymember)
So I inherited CustomAutoCompleteSuggestHelper of AutoCompleteSuggestHelper and overide DefaultFilter
protected override bool DefaultFilter(RadListDataItem item)
        {
            this.DropDownList.SortStyle = Telerik.WinControls.Enumerations.SortStyle.None;

            var newlist = item.Text.Split('[');
            return ((newlist[0].ToLower().Contains(this.Filter.ToLower())) || newlist[1].ToLower().Contains(this.Filter.ToLower()));
               
        }
and assigned this class to my dropdown
mydropdown.DropDownListElement.AutoCompleteSuggest = new CustomAutoCompleteSuggestHelper(mydropdown.DropDownListElement);


it works , but the problem is the DropDownList.SortStyle is changed.
For some reason I want it in none style mode  ,but by raising DefaultFilter it changed to Ascending mode


StackTrace:
AutoCompleteSuggestHelper.ApplyFilterToDropDown(string filter)
RadListElement.SetSortStyle(Telerik.WinControls.Enumerations.SortStyle value)
RadListElement.OnSortStyleChanged(Telerik.WinControls.Enumerations.SortStyle sortStyle) 


What should I do?
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 18 Jan 2018, 10:53 AM
Hello, Fariba,   

Thank you for writing.  

By default, the items displayed in the AutoCompleteSuggestHelper’s pop-up are sorted alphabetically. You can manipulate the sort order by using a custom comparer. A sample approach is demonstrated in the Customize auto-complete helpers section in the following help article: https://docs.telerik.com/devtools/winforms/dropdown-listcontrol-and-checkeddropdownlist/dropdownlist/features/auto-complete

I hope this information helps. Should you have further questions I would be glad to help. 
 
 Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Fariba
Top achievements
Rank 1
answered on 22 Jan 2018, 07:49 AM

I did as u said and I moved all my code to the Compare method of the CustomComparer

but now there is another problem and compare method raised all the time for comapring all the items of Data source and it made filtering to slow.

I try to make condition on filter length by  

  private bool FilterItem(RadListDataItem item)
        {
            if (this.Filter.Length > 2)
            {
                return true;
            }
            return false;
        } 

and assign it to the  CustomAutoCompleteSuggestHelper.DropDownList.Filter or raddropdownlist.filter.

But it does not work.

ApplyFilterToDropDown raised and by setting

this.DropDownList.ListElement.DataLayer.DataView.Comparer = new CustomCompare 

compare method raised all the time.

Is there any way to raised compare method by condition for example while the filter text length is more than 2 character .

 

 

 

Thanks 

Fariba

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 23 Jan 2018, 09:14 AM
Hello, Fariba,  

Thank you for writing back. 

It is normal that the custom comparer is called many times. With each action that needs to display the items it is required to order these items and then the comparer is used. Try to optimize the comparer. In the AutoCompleteSuggestHelper you can override the HandleAutoSuggest method and don't call the basic logic if you have less than 2 characters entered in the text box.

If you are still experiencing any further difficulties, feel free to submit a support ticket where you can provide a sampel project demonstrating the problem. Thus, our support staff will gladly assist you. 

I hope this information helps. If you have any additional questions, please let me know. 

 Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
DropDownList
Asked by
Aleksandr
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Aleksandr
Top achievements
Rank 1
Fariba
Top achievements
Rank 1
Share this question
or