RadAutoCompleteBox - Items collection ordered by input, not alphabetically

13 posts, 1 answers
  1. Per
    Per avatar
    4 posts
    Member since:
    Aug 2011

    Posted 29 Oct 2012 Link to this post

    Hi,

    When I loop though the Items collection in the RadAutoCompleteBox control, I've noticed the items are ordered alphabetically. Is it possible to receive this collection in the order they are entered in control because this order is important to me. It would be messy if I have to manually delimit the text property to get the item order and then manually match it with each entry in the items collection so that I can retrieve the value of each item as specified in the AutoCompleteValueMember property.

    Kind regards.
  2. Answer
    Anton
    Admin
    Anton avatar
    167 posts

    Posted 31 Oct 2012 Link to this post

    Hello Per,

    Thank you for writing.

    The Items collection in the RadAutoCompleteBox is designed to be alphabetically ordered. However you can easy to achieve desired behavior by subscribing to the Items.CollectionChanged event and using your own collection that holds the items ordered by the desired criteria. For example:
    List<RadTokenizedTextItem> list;
    void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            for (int i = 0; i < e.NewItems.Count; i++)
            {
              list.Add(e.NewItems[i] as RadTokenizedTextItem);
            }                
        }
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            for (int i = 0; i < e.NewItems.Count; i++)
            {
                list.Remove(e.NewItems[i] as RadTokenizedTextItem);
            
        }
    }
    Attached is a sample project that comprises the code above. 

    Should you have any other questions, I will be glad to assist you.

    Regards,
    Anton
    the Telerik team
    Q3’11 of RadControls for WinForms is available for download (see what's new). Get it today.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Per
    Per avatar
    4 posts
    Member since:
    Aug 2011

    Posted 01 Nov 2012 Link to this post

    Hi Anton,

    Thanks for your code snippet. Unfortunately, I was a little unclear in my original question. My original question should have stated that I wanted a collection that contains a list of tokens as they are ordered in the Text value of the control.

    For example, I start by entering the token "Apple". If I then move the cursor to the start of the control and enter a new token "Banana" so that the Text value of the control is "Banana;Apple;", your code snippet creates a collection in the order they were entered {"Apple", "Banana"}, however I would like a collection as they appear in the Text value {"Banana", "Apple"}.

    Removing a token also does not correctly handle removing the non-first occurrence of a token that is recorded multiple times. For example, if I enter the tokens {"Apple", "Banana", "Carrot", "Banana"} and subsequently delete the second occurrence of "Banana", the Remove method of List object removes the first occurrence of "Banana" instead of the second occurrence.

    However, thank you for the starting point with the code snippet.

    Kind regards.
  5. Anton
    Admin
    Anton avatar
    167 posts

    Posted 05 Nov 2012 Link to this post

    Hello Per,

    Thank you for back.

    Currently, the RadAutoCompleteBox does not support the described scenario and there is no workaround for it.
    I have logged this case in PITS http://www.telerik.com/support/pits.aspx#/public/winforms/13279 as feature request and we will address it in the upcoming Q3 2012 SP1 release, due by the end of the month. Also I have updated your Telerik points.

    The only solution that I can give you now is how to take the text of the items in desired order:
    foreach (RadElement element in this.radAutoCompleteBox1.TextBoxElement.ViewElement.Children)
    {
        TokenizedTextBlockElement token = element as TokenizedTextBlockElement;
     
        if (token != null)
        {
            this.radLabel1.Text += token.ContentElement.Text;
        }
    }

    I hope this helps.

    Kind regards,
    Anton
    the Telerik team
    Q3’11 of RadControls for WinForms is available for download (see what's new). Get it today.
  6. David
    David avatar
    57 posts
    Member since:
    Apr 2011

    Posted 13 Dec 2012 Link to this post

    Hi Anton,

    I've downloaded and installed 2012 S3 SP1 (2012.3.1211.40), which has the following release history:

    RadAutoCompleteBox
    • IMPROVED: Changed the order of items in the Items collection. Now items are not sorted alphabetically.
    http://www.telerik.com/products/winforms/whats-new/release-history/q3-2012-sp1-version-2012-3-1211-3078762224.aspx

    However, iterating the Items collection is still in alphabetical and not sequential order. Is there I need to do to activate sequential ordering?

    Kind regards,
    Dave.
  7. Anton
    Admin
    Anton avatar
    167 posts

    Posted 14 Dec 2012 Link to this post

    Hello David,

    Thank you for writing back.

    Now you can achieve the desired items order by the following steps:

    1. Create a custom text block element that derives from TokenizedTextBlockElement.
    public class MyTokenizedTextBlockElement : TokenizedTextBlockElement
    {
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(TokenizedTextBlockElement);
            }
        }
     
        protected override RadTokenizedTextItem CreateTokenizedTextItem(string text, object value)
        {
            return new MyRadTokenizedTextItem(text, value, this);
        }
    }

    2. Create a custom tokenized text item collection that derives from RadTokenizedTextItemCollection
    public class MyRadTokenizedTextItemCollection : RadTokenizedTextItemCollection
    {
        public MyRadTokenizedTextItemCollection(RadAutoCompleteBoxElement box)
            : base(box, new List<RadTokenizedTextItem>())
        {
     
        }
     
        protected override void OnCollectionChanged(Telerik.WinControls.Data.NotifyCollectionChangedEventArgs e)
        {
            List<RadTokenizedTextItem> tokens = this.Items as List<RadTokenizedTextItem>;
            tokens.Sort();
            base.OnCollectionChanged(e);
        }
    }

    3. Create a custom tokenized text item that derives from RadTokenizedTextItem.
    public class MyRadTokenizedTextItem : RadTokenizedTextItem
    {
        private ITextBlock owner;
     
        public MyRadTokenizedTextItem(string text, object value, ITextBlock owner)
            : base(text, value)
        {
            this.owner = owner;
        }
     
        public override int CompareTo(RadTokenizedTextItem other)
        {
            MyRadTokenizedTextItem token = other as MyRadTokenizedTextItem;
            return Comparer<int>.Default.Compare(owner.Index, token.owner.Index);
        }
    }

    4. Create a custom auto-complete text box.
    public class MyRadAutoCompleteBox: RadAutoCompleteBox
    {
        public MyRadAutoCompleteBox()
        {
            this.ThemeClassName = typeof(RadAutoCompleteBox).FullName;
        }
     
        protected override RadTextBoxControlElement CreateTextBoxElement()
        {
            return new MyRadAutoCompleteBoxElement();
        }
    }
     
    public class MyRadAutoCompleteBoxElement : RadAutoCompleteBoxElement
    {
        protected override RadTokenizedTextItemCollection CreateTokenizedItemCollection()
        {
            return new MyRadTokenizedTextItemCollection(this);
        }
     
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(RadAutoCompleteBoxElement);
            }
        }
    }

    5. Use the custom auto-compete text box instead the RadAutoCompleteTextBox.

    Attached is a sample project that demonstrates how the code above works. I hope this helps.

    Should you have any other questions, I will be glad to assist you.

    Kind regards,
    Anton
    the Telerik team
    Q3’12 of RadControls for WinForms is available for download (see what's new). Get it today.
  8. Bhushan
    Bhushan avatar
    3 posts
    Member since:
    Jul 2014

    Posted 18 Jul 2014 in reply to Anton Link to this post

    Hi Sir I am using the RadAutocomplete TextBox.When User select any value from suggested list in autocomplete textbox it shouls not get repeted....means in that textbox same value should not be repeated after selecting from that suggested list..So How Can i Do That??
    I am new Bee  TO the telerik Controls
    Please Give me Solutions
  9. Bhushan
    Bhushan avatar
    3 posts
    Member since:
    Jul 2014

    Posted 18 Jul 2014 in reply to Anton Link to this post

    Resp sir,
    if i add same item multiple time then is there any provision to remove it?
    if yes then how can i remove the same records and keep only one out of that.please give me solution i am new bie to this telerik controls
  10. Dess
    Admin
    Dess avatar
    1609 posts

    Posted 22 Jul 2014 Link to this post

    Hello Bhushan,

    Thank you for writing.

    The TokenValidating event gives the user the opportunity to validate the entered token. The IsValidToken argument in the TokenValidatingEventArgs indicates whether the text will be added as a token. Here is a sample code snippet:
    private void Form1_Load(object sender, EventArgs e)
    {
        this.customersTableAdapter.Fill(this.nwindDataSet.Customers);
     
        this.radAutoCompleteBox1.AutoCompleteDataSource = this.customersBindingSource;
        this.radAutoCompleteBox1.AutoCompleteDisplayMember = "ContactName";
        this.radAutoCompleteBox1.AutoCompleteValueMember = "CustomerID";
     
        this.radAutoCompleteBox1.TokenValidating += radAutoCompleteBox1_TokenValidating;
    }
     
    private void radAutoCompleteBox1_TokenValidating(object sender, TokenValidatingEventArgs e)
    {
        foreach (var item in this.radAutoCompleteBox1.Items)
        {
            if (item.Text == e.Text)
            {
                if (RadMessageBox.Show("Should I create duplicate item: " + e.Text, "Action needed",
                    MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
                {
                    e.IsValidToken = false;
                }
                break;
            }
        }
    }

    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.
     
  11. Gyan
    Gyan avatar
    1 posts
    Member since:
    Apr 2015

    Posted 07 May 2015 Link to this post

    Hi,

    I tried the sample provided to control sorting of the filtered items in RadAutoCompleteBox. I implemented the control and tried to bind it with IEnumerable List but it didn't return the results in the order as was added in list but sorted alphabetically(default behavior). When I used datatable to bind the control it worked and kept the order of filtered items same as they were added to datable.

    In both the scenarios the query used to fill the source was same. Could you please explain the difference in behavior and if it is possible to control auto sorting with IEnumerable list?

  12. Dess
    Admin
    Dess avatar
    1609 posts

    Posted 08 May 2015 Link to this post

    Hello Gyan,

    Thank you for writing.

    I have modified the project provided by Anton on a way to sort the tokenized items by their text length. Please refer to the custom RadTokenizedTextItem class and its CompareTo method. The attached gif file illustrates how the items are sorted by their text length. If you use the commented code in the CompareTo method instead, the tokenized items will be displayed after the button click sorted by input order.
    public override int CompareTo(RadTokenizedTextItem other)
    {
        MyRadTokenizedTextItem token = other as MyRadTokenizedTextItem;
        return Comparer<int>.Default.Compare(owner.Index, token.owner.Index);//sort by text length
     
        //return Comparer<int>.Default.Compare(this.Text.Length, token.Text.Length); sort by input order
    }

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

    See What's Next in App Development. Register for TelerikNEXT.

     
  13. Marika
    Marika avatar
    1 posts
    Member since:
    Jun 2012

    Posted 10 May 2015 in reply to Dess Link to this post

    Hi Dess,

    Thanks for suggestion. The method works fine when I bind datatable as datasource with the control but doesn't work with IEnumerable list. With IEnumerable list, it always sort alphabetically. Could you please explain the behavior?

  14. Dess
    Admin
    Dess avatar
    1609 posts

    Posted 11 May 2015 Link to this post

    Hello Marika,

    Thank you for writing back.

    The RadAutoCompleteBox.AutoCompleteDataSource property is set to an IEnumerable<Item> collection in the attached sample project from my previous post. Could you please describe how exactly it differs from your real setup? It would be greatly appreciated if you specify how to reproduce the problem? Alternatively, you can provide a sample project replicate the issue in the support ticket that you have opened on the same topic.

    I am looking forward to your reply.

    Regards,
    Dess
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
UI for WinForms is Visual Studio 2017 Ready