Telerik blogs

In Q2 2012 we introduced a cool brand new control in Telerik’s WinForms suite – RadAutoCompleteBox. This control allows end-users to easily fill-in text thanks to autocomplete functionality and tokens of text coming “out of the box”. This behavior enables you to easily simulate the  Outlook and Facebook autocomplete functionality available to users each time they send a new message and pick the recipients  in the ‘To:’ field of their outgoing message from a convenient pop-up list with suggestions. 

RadAutoCompleteBox for WinForms

In the following example, I am going to demo a solution to a real-world scenario in which we need to achieve the visual appearance you get in Outlook when some of your recipients are online, others are offline or away, and there are some external parties for your organization involved in the communication, so you are not able to pull out their availability status. This is what we will end up with:

RadAutoCompleteBox for WinForms with Statuses

As you can see above, Lee Cooper is marked as offline, Adam Peter is marked as busy, Joe Smith is away, Daniel Finger is online, there is one e-mail address  unknown to our organization, and we are about to enter a suggested name starting with “R”. So let’s see how this is done.

Setting auto-complete data

Starting from the ground up, let’s first analyze how RadAutoCompleteBox becomes aware of the data suggestions that it should pop up as you type. You can add such data manually by adding RadListDataItems to its AutoCompleteItems collection like shown below:
RadListDataItemCollection items = this.radAutoCompleteBox1.AutoCompleteItems;
items.Add(new RadListDataItem("Joe Smith", ""));
items.Add(new RadListDataItem("Adam Petersen", ""));

For our case, however, we are going to use the data-bound approach that RadAutoCompleteBox offers. In this approach, we should have at hand a data-structure of sample Persons where each person has a FullName, an Email address, and a Status:
BindingList<Person> persons = new BindingList<Person>();
persons.Add(new Person(0, "Joe Smith", "", Status.Away));
persons.Add(new Person(6, "Lee Cooper", "", Status.Offline));
persons.Add(new Person(1, "Adam Petersen", "", Status.Busy));
persons.Add(new Person(3, "Daniel Finger", "", Status.Online));
// Persons skipped for brevity

Then, we should simply bind RadAutoCompleteBox to that data using the AutoCompleteDataSource, AutoCompleteValueMemeber and AutoCompleteDisplayMember properties:
this.radAutoCompleteBox1.AutoCompleteDataSource = persons;
this.radAutoCompleteBox1.AutoCompleteValueMember = "Email";
this.radAutoCompleteBox1.AutoCompleteDisplayMember = "FullName";

As the background is set, it now comes the interesting part. 

Data Validation

The data validation occurs at the TokenValidating event where, based on some conditions, we should decide where the data entered in the control should be tokenized or not. Our requirement is to have text that matches a known FullName or text that represents an e-mail address:
void radAutoCompleteBox1_TokenValidating(object sender, TokenValidatingEventArgs e)
    // sample mail validation for brevity
    bool isEmailAddress = e.Text.Contains('@');
    bool isKnownPerson = persons.Where(x => x.FullName.Equals(e.Text)).FirstOrDefault() != null;
    e.IsValidToken = isEmailAddress || isKnownPerson;

Plugging in custom tokens

From the screenshot at the top you should have noticed that the tokens contain little circles that provide information about the status of the persons. These circular images, however, do not come with RadAutoCompleteBox by default, so we should add them to the project and extend the default token to support them. Here is how the extended version of the token can be implemented:
public class TokenizedBlockWithStatusBullet : TokenizedTextBlockElement
     private LightVisualElement statusBullet;
     protected override Type ThemeEffectiveType
     { get { return typeof(TokenizedTextBlockElement); } }
     protected override void CreateChildElements()
          this.statusBullet = new LightVisualElement();
          this.statusBullet.StretchVertically = true;
          this.statusBullet.StretchHorizontally = false;
          this.statusBullet.Margin = new System.Windows.Forms.Padding(5, 0, 0, 0);
          this.Children.Insert(0, this.statusBullet);
            this.statusBullet.Image = RadAutoCompleteBoxWF.Properties.Resources.status_offline;
     public Image StatusImage
     { get { return statusBullet.Image; }
      set { statusBullet.Image = value; } }

Basically, here we complement the default token implementation with a single LightVisualElement – one of the basic types of bricks that form the look of many RadControls. Later, we’ll be able to further customize the circular image next to this LightVisualElement.

Formatting the tokens

Finally, we should define the look of the tokens depending on the status of the Person that is entered. This operation should be done in the TextBlockFormatting event:
void radAutoCompleteBox1_TextBlockFormatting(object sender, TextBlockFormattingEventArgs e)
    TokenizedBlockWithStatusBullet token = e.TextBlock as TokenizedBlockWithStatusBullet;
    Person p = persons.Where(x => x.FullName.Contains(e.TextBlock.Text)).FirstOrDefault();
    if (p != null)
        switch (p.Status)
            case Status.Offline:
                token.BackColor = Color.LightGray;
                token.BorderColor = Color.DarkGray;
                token.StatusImage = RadAutoCompleteBoxWF.Properties.Resources.status_offline;
            case Status.Away:
                token.BackColor = Color.Yellow;
                token.BorderColor = Color.Orange;
                token.StatusImage = RadAutoCompleteBoxWF.Properties.Resources.status_away;
                 // Status.Busy and Status.Online skipped for brevity

This is it! Now if the entered text matches a known Person, the token will be colored according to the status.

Check our Getting Started with RadAutoCompleteBox for WinForms video that guides you through this scenario in a friendly step-by-step manner.

Download RadControls for WinForms by Telerik

About the Author

Nikolay Diyanov

Diyanov is the Product Manager of the Native Mobile UI division at Progress. Delivering outstanding solutions that make developers' lives easier is his passion and the biggest reward in his work. In his spare time, Nikolay enjoys travelling around the world, hiking, sun-bathing and kite-surfing.

Find him on Twitter @n_diyanov or on LinkedIn.

Related Posts


Comments are disabled in preview mode.