Data Annotation Attributes

  • 13 minutes to read

DevExpress data-aware controls (GridControl, TreeList, VGridControl, PropertyGridControl and Data Layout Control) support Data Annotation Attributes provided by Microsoft. You can define these attributes when creating your data source in code. The grids and treelists that uses this data as their data source will recognize the attributes and automatically tweak their columns - re-arrange them, change their captions, format cell data, apply filters or validation etc. This means that using Data Annotation Attributes allows you to completely disregard the control designer, since none of the columns require manual customization.

For the Data Layout Control, even more complex UI customization is supported - certain data attributes not only allow you to apply display formats and validation rules, but to group layout items into specific groups and tabbed containers. See the Data Annotation Attributes in Data Layout Control topic to learn more.

To see a complete Data Annotation Attributes list, see this MSDN article. The tables below list the most common and frequently used attributes supported by the Grid Control and TreeList Control.

Data Display Attributes

Attribute

Parameter (if any)

Description

Code Sample

Display

Name

Specifies the column caption for the auto-generated column. This attribute has no effect on columns created at design-time. Column captions set by this attribute can be overridden by using the GridColumn.Caption property.

Grid Control - Data Annotation Attributes - Name

[Display(ShortName = "Company", Name = "Company Name")]
public string CompanyName { get; set; }

AutoGenerateField

Specifies whether a control automatically generates a column for this field.

[Display(AutoGenerateField = false, Description = "This column isn't created")]
public string AdditionalInfo { get; set; }

AutoGenerateFilter

Specifies whether the filter UI is automatically generated for this field. Applies to automatically generated columns only. If a column is created manually, use the OptionsColumnFilter.AllowFilter property to generate the filter UI for that column.

[Display(AutoGenerateFilter = false)]
public string Email { get; set; }

Order

Specifies the display order for this column (see the GridColumn.VisibleIndex property).

Can be set to -1 to hide this column.

Grid Control - Data Annotation Attributes - Order

[Display(Order = 2)]
public string Country { get; set; }
[Display(Order = 1)]
public string City { get; set; }

Description

Assigns a tool-tip to this column. The GridColumn.ToolTip property overrides this attribute description.

Grid Control - Data Annotation Attributes - Description

[Display(Description = "The amount of currently available product")]
public int Quantity { get; set; }

Editable

Specifies whether this column can be edited (see the OptionsColumn.AllowEdit property).

[Editable(false)]
public string City { get; set; }

ReadOnly

Gets or sets whether this column is in read only mode (OptionsColumn.ReadOnly).

[ReadOnly(true)]
public double UnitPrice { get; set; }

DisplayFormat

DataFormatString

Specifies the display format for this column's records.

Grid Control - Data Annotation Attributes - DataFormatString

[DisplayFormat(DataFormatString = "MMMM/yyyy")]
 public object Date2 { get; set; }

ApplyFormatInEditMode

Specifies whether the current display format for this cell should remain visible when this cell is being edited.

Grid Control - Data Annotation Attributes - FormatInEditMode

[DisplayFormat(DataFormatString = "p", ApplyFormatInEditMode = true)]
public object SalesVsTarget { get; set; }

Data Type Attributes

Attribute

Parameter (if any)

Description

Code Sample

MetadataType

Allows you to derive data annotation attributes from another class.

[MetadataType(typeof(CompanyProductMetadata))]
public class Product {
    public double UnitPrice { get; set; }
}

public class CompanyProductMetadata {
    [ReadOnly(true)]
    public double UnitPrice { get; set; }
}

DataType

Specifies the type of this column's data.

Based on this info the grid control, applies the specific formatting and chooses the appropriate editor for column cells.

Grid Control - Data Annotation Attributes - DataType

[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }

EnumDataType

Allows you to replace numeric enumerator values with corresponding declarations.

Grid Control - Data Annotation Attributes - EnumType

[EnumDataType(typeof(ProductCategory))]
public int Category { get; set; }

public enum ProductCategory {
    Beverages = 1,
    Fruit = 2,
    Vegetables = 3,
    Meat = 4,
    Condiments = 5,
    Confections = 6,
    DairyProducts = 7,
    GrainsCereals = 8,
    Seafood = 9
}

Validation Attributes

Attribute

Parameter (if any)

Description

Code Sample

StringLength

Specifies the maximum and minimum number of characters for string records within this column.

Grid Control - Data Annotation Attributes - StringLength

[DataType(DataType.Password), StringLength(20, MinimumLength = 3)]
public string Password { get; set; }

Range

All numeric records of this column should lie in specific range, set by using this attribute.

Grid Control - Data Annotation Attributes - Range

[DataType(DataType.Currency), Range(200, 5000)]
public int Currency { get; set; }

Required

If used, restricts an end-user leaving a cell within this column if this cell is currently empty.

Grid Control - Data Annotation Attributes - Required

[DataType(DataType.PhoneNumber), Required]
public string Phone { get; set; }

Compare

Compares the field with another property. Entering values that differ from the compared column's value is restricted.

XtraGrid - Data Annotation Attributes - Compare

[DataType(DataType.Password), Display(Name = "New Password")]
public string NewPassword { get; set; }

[DataType(DataType.Password), Compare("NewPassword",
     ErrorMessage="The new and confirmation passwords do not match"),
     Display(Name="Confirm Password")]
public string ConfirmPassword { get; set; }

Also refer to the Data Binding topic to learn more about using Fluent API to add new and modify existing columns in Entity Framework Code First models.

Example

The solution in this example includes a DataSource file that has three classes that provide grid data - CompanyPublicInfo, CompanyPrivateInfo and Product. Properties for all three of them derive Data Annotation Attributes from the CompanyProductMetadata class by using the MetadataType attribute. End-users can use the editor at the top of the form to call one of the Get... methods that will populate the grid with sample data.

IMPORTANT

To work with Data Annotation Attributes, you need to reference the System.ComponentModel.DataAnnotations library in your solution.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GridDataAttributes {
    [MetadataType(typeof(CompanyProductMetadata))]
    public class CompanyPublicInfo {
        public string CompanyName { get; set; }
        public string Country { get; set; }
        public string City { get; set; }
        public string Url { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string AdditionalInfo { get; set; }
    }

    [MetadataType(typeof(CompanyProductMetadata))]
    public class CompanyPrivateInfo {
        public string Password { get; set; }
        public DateTime Date2 { get; set; }
        public double Sales { get; set; }
        public double Profit { get; set; }
        public double SalesVsTarget { get; set; }
        public double MarketShare { get; set; }
        public double CustomersSatisfaction { get; set; }
    }

    public class Product {
        [ReadOnly(true)]
        public double UnitPrice { get; set; }
        [EnumDataType(typeof(ProductCategory))]
        public int Category { get; set; }
        [Display(Description = "The amount of currently available product")]
        public int Quantity { get; set; }
        [DataType(DataType.Text), Display(Order = -1)]
        public string Text { get; set; }
        [DataType(DataType.MultilineText)]
        public string MultilineText { get; set; }
        [DataType(DataType.Currency), Range(200, 5000)]
        public int Currency { get; set; }
        [DataType(DataType.Date)]
        public DateTime Date { get; set; }
        [DataType(DataType.Time)]
        public DateTime Time { get; set; }
    }

    public class CompanyProductMetadata {
        [Display(ShortName = "Company", Name = "Company Name", AutoGenerateFilter = false)]
        public object CompanyName;
        [Display(Order = 2)]
        public object Country;
        [Display(Order = 1), Editable(false)]
        public object City;
        [DataType(DataType.Url)]
        public object Url;
        [DataType(DataType.EmailAddress)]
        public object Email;
        [DataType(DataType.PhoneNumber), Required]
        public object Phone;
        [DataType(DataType.Text), Display(Order = -1)]
        public object Text;
        [Display(AutoGenerateField = false, Description = "This column isn't created")]
        public object AdditionalInfo;
        [DataType(DataType.Password), StringLength(20, MinimumLength = 3)]
        public object Password;
        [DisplayFormat(DataFormatString = "MMMM/yyyy"), Display(Name = "Date 2")]
        public object Date2;
        [DisplayFormat(DataFormatString = "#,##0,,M")]
        public object Sales;
        [DisplayFormat(DataFormatString = "#,##0,,M")]
        public object Profit;
        [DisplayFormat(DataFormatString = "p", ApplyFormatInEditMode = true), Display(Name = "Sales vs Target")]
        public object SalesVsTarget;
        [DisplayFormat(DataFormatString = "p0", ApplyFormatInEditMode = false)]
        public object MarketShare;
        [Display(Name = "Cust Satisfaction")]
        public object CustomersSatisfaction;
    }

    public enum ProductCategory {
        Beverages = 1,
        Fruit = 2,
        Vegetables = 3,
        Meat = 4,
        Condiments = 5,
        Confections = 6,
        DairyProducts = 7,
        GrainsCereals = 8,
        Seafood = 9
    }

    public class GridSampleDataList {
        static public List<CompanyPrivateInfo> GetCompanyPrivateInfo() {
            return new List<CompanyPrivateInfo> {
                        new CompanyPrivateInfo() {
                            CustomersSatisfaction = 3.1,
                            Date2 = DateTime.Now,
                            MarketShare = 42,
                            Password = "123qwerty",
                            Profit = 4951515,
                            Sales = 311414134,
                            SalesVsTarget = 0.0277,
                        }
                    };
        }
        static public List<CompanyPublicInfo> GetCompanyPublicInfo() {
            return new List<CompanyPublicInfo> {
                        new CompanyPublicInfo() {
                            AdditionalInfo = "Some Info",
                            City = "Glendale",
                            CompanyName = "Developer Express",
                            Country = "USA",
                            Email = "info@devexpress.com",
                            Phone = "1234567890",
                            Url = "www.devexpress.com",
                        }
                    };
        }
        static public List<Product> GetProductSample() {
            return new List<Product> {
                        new Product() {
                            Currency = 1000,
                            Category = 2,
                            Date = DateTime.Now,
                            MultilineText = "Line1\r\nLine2\r\nLine3",
                            Quantity = 321,
                            Text = "Sample Text",
                            Time = DateTime.Now,
                            UnitPrice = 1800,
                        }
                    };
        }
    }
}