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.
14 Answers, 1 is accepted
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);
}
}
}
Should you have any other questions, I will be glad to assist you.
Regards,
Anton
the Telerik team
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.
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
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.
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.
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
I am new Bee TO the telerik Controls
Please Give me Solutions
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
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
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?
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.
Dess
Telerik
See What's Next in App Development. Register for TelerikNEXT.
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?
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.
Since the Items collection in RadAutoCompleteBox is designed to be alphabetically ordered, we haven't made any changes on this matter. Feel free to use the previously suggested approaches that controls how the items are ordered.
If you need any further assistance please don't hesitate to contact me.
Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.