Token Edit Control
- 7 minutes to read
The WinForms Token Edit Control allows users to select items from a drop-down menu. Selected items are displayed as blocks called tokens. Each block has a “Remove” button that allows users to quickly deselect this token.
Tokens
Each token stores a unique value. At runtime, tokens show a description string, an optional image, and a hover background. Tokens are instances of the TokenEditToken
class.
Description
Token descriptions are stored in the TokenEditToken.Description
property. You can handle the TokenEdit.CustomDrawTokenText event to replace text without changing Description property values.
private void tokenEdit1_CustomDrawTokenText(object sender, TokenEditCustomDrawTokenTextEventArgs e) {
if (. . .) e.Info.PaintAppearance.DrawString(
e.Cache, "Custom Text", e.Info.DescriptionBounds, e.Info.PaintAppearance.Font,
Brushes.Black, e.Info.PaintAppearance.GetStringFormat());
e.Handled = true;
}
Value
Tokens store values in their TokenEditToken.Value
properties. When a user selects a token, the control adds this token value to its BaseEdit.EditValue property. Depending on the Properties.EditValueType property value, the control’s EditValue can be a string, a BindingList, or an enumeration.
Important
- Every token must have a value.
- Token values must be unique.
- TokenEdit uses the
ToString()
method to compare token values. If you use objects of a custom class as token values, override the classToString()
method so that every object returns a unique value. See the following help topic for an example: How to: Use complex objects as token values.
Image
Tokens can show images (glyphs) before or after their descriptions. When a user clicks an image, the control deselects this token.
- Properties.ShowTokenGlyph - specifies whether tokens should display their icons.
- Properties.TokenGlyphLocation - gets or sets whether tokens should display their icons before or after descriptions.
- Properties.DeleteTokenOnGlyphClick - specifies whether the Token Edit should deselect tokens when a user clicks their icons.
- Properties.CustomDrawTokenGlyph - allows you to replace default cross icons with custom images.
Add Tokens
Token Edit supports two token types:
- unbound tokens that you add at design time or in code.
- bound tokens that the control generates based on data source records.
Note that you cannot mix token types: if a control has a data source, unbound tokens are disabled.
Unbound Tokens
Unbound tokens are stored in the Properties.Tokens collection. To add unbound tokens, click the ellipsis button next to the Tokens
property in the Visual Studio Properties window, and use the Collection Editor dialog.
To add unbound tokens in code, call Tokens
collection methods between the BeginUpdate
-EndUpdate
method calls.
tokenEdit1.Properties.BeginUpdate();
tokenEdit1.Properties.Tokens.AddToken("Description string", "value");
// ... add more tokens
tokenEdit1.Properties.EndUpdate();
Bound Tokens
Use the Properties.DataSource property to bind a control to a data source, and specify two more properties:
- Properties.DisplayMember - the data source field that stores token descriptions;
- Properties.ValueMember - the data source field that stores token values. Token values must be unique.
tokenEdit1.Properties.DataSource = queryBindingSource;
tokenEdit1.Properties.DisplayMember = "EmailAddress";
tokenEdit1.Properties.ValueMember = "EmailAddressID";
Drop-down Menu
The drop-down window that contains tokens can be opened if the following options are enabled:
- ShowDropDown — specifies whether the drop-down window is shown when the user starts typing into the edit box. The drop-down window contains only tokens that start with the entered text. If there are no tokens that start with this text, all tokens are shown.
- ShowDropDownOnClick — specifies whether the drop-down window is shown when the user clicks within the edit box. The drop-down window contains all available tokens.
If the user has selected all available tokens, the drop-down window is not opened. You can also use the MaxTokenCount property to specify the maximum number of tokens that the user can select. If this value is reached, the drop-down window is not opened.
The list below enumerates drop-down menu settings.
Properties.DropDownRowCount - the maximum number of tokens a menu can show. The default value is 7.
Properties.DropDownShowMode - allows you to choose between Regular and Outlook display modes.
- In Regular mode, the drop-down menu width is always equal to the editor width.
- In Outlook mode, the drop-down menu width is limited by the longest token. The menu is displayed under the current cursor position.
Properties.ShowRemoveTokenButtons - specifies whether the drop-down menu allows users to remove tokens from the list.
When a user clicks this button, the RemoveTokenButtonClick event fires. This event allows you to ignore the user click action and leave the item in the drop-down menu. If the Token Edit has a data source, use this event to remove data source records.Properties.CustomDropDownControl - allows you to use any custom panel as a drop-down menu. See the following help topic for an example: TokenEdit with Custom Drop-Down Control.
TokenEdit.ShowPopup() - call this method to open the Token Edit drop-down menu.
Add Tokens at Runtime
To allow users to add new tokens at runtime, switch the Properties.EditMode property to TokenEditMode.Manual
. In this mode, users can type any text in the editor text box. When they type a separator character (the default separator is a comma (“,”); you can add more to the Separators collection), the editor fires an event that allows you to process the user input.
In unbound mode (when a Token Edit has no data source), the editor fires the ValidateToken event. If you set the event’s e.IsValid
parameter to true, the editor accepts the entered text as a new token.
The code sample below illustrates how to accept only email addresses as tokens.
using System.Text.RegularExpressions;
Regex MailRegex =
new Regex(@"^[-a-z0-9!#$%&'*+/=?^_`{|}~]+(?:\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*" +
"@(?:[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?\\.)*" +
"(?:aero|arpa|asia|biz|cat|com|coop|edu|gov|" +
"info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z][a-z])$",
RegexOptions.Compiled);
private void ValidateToken(object sender, TokenEditValidateTokenEventArgs e) {
e.IsValid = MailRegex.IsMatch(e.Description);
}
In bound mode, the editor fires the ProcessNewValue event. Handle it to check the user input, and if you accept it as a valid token, add a corresponding new record to the data source.
void TokenEdit1_ProcessNewValue(object sender, TokenEditProcessNewValueEventArgs e) {
if (MailRegex.IsMatch(e.Text)) {
//use data source API to post changes
e.Handled = true;
}
}
Peek Panel
To display a Peek Panel when a user moves the mouse pointer over a token, assign a FlyoutPanel to the Properties.PopupPanel property.
Before a panel is displayed on-screen, the editor fires the RepositoryItemTokenEdit.BeforeShowPopupPanel event.
Event arguments expose the following properties:
e.Token
- the hovered token;e.Value
,e.Description
- the value and description of the hovered token;e.DataObject
- in bound mode, returns an Object that is the data source record. In unbound mode, returns the hovered token as an Object.e.DataSourceIndex
- in bound mode, returns the index of a data source record. In unbound mode, returns the index of the hovered token within the RepositoryItemTokenEdit.Tokens collection.e.Bounds
- flyout panel bounds.
The code below populates two flyout panel labels with the token description and the value of the corresponding data source record’s “Modified Date” column.
void TokenEdit1_BeforeShowPopupPanel(object sender, TokenEditBeforeShowPopupPanelEventArgs e) {
labelControl2.Text = e.Token.Description;
labelControl4.Text = (e.DataObject as DevExpress.DataAccess.Sql.DataApi.IRow)["ModifiedDate"].ToString();
}
Optional Peek Panel settings:
- Properties.PopupPanelOptions.ShowPopupPanel - disable this property to hide Peek Panels;
- Properties.PopupPanelOptions.Location - allows you to choose whether Peek Panels should pop up above tokens, below them, or at the current cursor position.