Back to Devexpress

Tutorial: Create and Manage Data in Code and Apply Data Annotation Attributes

windowsforms-114704-controls-and-libraries-data-grid-getting-started-walkthroughs-data-binding-and-working-with-columns-tutorial-create-and-manage-data-in-code-and-apply-data-annotation-attributes.md

latest32.8 KB
Original Source

Tutorial: Create and Manage Data in Code and Apply Data Annotation Attributes

  • May 04, 2024
  • 17 minutes to read

This walkthrough is a transcript of the Create and Manage Data in Code and Apply Data Annotation Attributes video available on the DevExpress YouTube Channel.

In this tutorial, you will learn how to create a data source for your grid control in code. You will also see how to apply data attributes to make the grid apply appropriate editing modes, cell editors and input validation rules.

Creating a Simple Data Source Using DevExpress Project Wizard

Start by creating a project with the DevExpress Project Wizard available at the DevExpress Templates collection as you create a new solution.

Launch the app to see that there’s sample data displayed by the grid.

Switch to code to locate the source of this data. There’s code automatically generated by the wizard, including the InitGrid method call in the form constructor. This method populates a BindingList with 5 instances of the Person class. The BindingList object is then assigned to the gird control’s GridControl.DataSource property.

csharp
class Person {
    string firstName;
    string secondName;
    string comments;
    public Person(string firstName, string secondName) {
        this.firstName = firstName;
        this.secondName = secondName;
        comments = String.Empty;
    }
    public Person(string firstName, string secondName, string comments)
        : this(firstName, secondName) {
        this.comments = comments;
    }
    public string FirstName {
        get { return firstName; }
        set { firstName = value; }
    }
    public string SecondName {
        get { return secondName; }
        set { secondName = value; }
    }
    public string Comments {
        get { return comments; }
        set { comments = value; }
    }
}

public Form1() {
    // ...
    InitGrid();
}

BindingList<Person> gridDataList = new BindingList<Person>();
void InitGrid() {
    gridDataList.Add(new Person("John", "Smith"));
    gridDataList.Add(new Person("Gabriel", "Smith"));
    gridDataList.Add(new Person("Ashley", "Smith", "some comment"));
    gridDataList.Add(new Person("Adrian", "Smith", "some comment"));
    gridDataList.Add(new Person("Gabriella", "Smith", "some comment"));
    gridControl.DataSource = gridDataList;
}
vb
Friend Class Person
    Private firstName_Renamed As String
    Private secondName_Renamed As String
    Private comments_Renamed As String
    Public Sub New(ByVal firstName As String, ByVal secondName As String)
        Me.firstName_Renamed = firstName
        Me.secondName_Renamed = secondName
        comments_Renamed = String.Empty
    End Sub
    Public Sub New(ByVal firstName As String, ByVal secondName As String, ByVal comments As String)
        Me.New(firstName, secondName)
        Me.comments_Renamed = comments
    End Sub
    Public Property FirstName() As String
        Get
            Return firstName_Renamed
        End Get
        Set(ByVal value As String)
            firstName_Renamed = value
        End Set
    End Property
    Public Property SecondName() As String
        Get
            Return secondName_Renamed
        End Get
        Set(ByVal value As String)
            secondName_Renamed = value
        End Set
    End Property
    Public Property Comments() As String
        Get
            Return comments_Renamed
        End Get
        Set(ByVal value As String)
            comments_Renamed = value
        End Set
    End Property
End Class

Public Sub New()
    ' ...
    InitGrid()
End Sub

Private gridDataList As New BindingList(Of Person)()
Private Sub InitGrid()
    gridDataList.Add(New Person("John", "Smith"))
    gridDataList.Add(New Person("Gabriel", "Smith"))
    gridDataList.Add(New Person("Ashley", "Smith", "some comment"))
    gridDataList.Add(New Person("Adrian", "Smith", "some comment"))
    gridDataList.Add(New Person("Gabriella", "Smith", "some comment"))
    gridControl.DataSource = gridDataList
End Sub

This is how you can create data in code in the simplest case. Define an object representing a record, then create a collection of such objects and assign the collection to the grid’s GridControl.DataSource property.

Creating More Complex Data Source

Now see a few more examples of creating data in code and then binding it to the grid.

You can define your custom classes that would serve as data records. The sample code file in this tutorial contains definitions of 3 classes: CompanyPublicInfo , CompanyPrivateInfo and Product , each including its own properties that will serve as data fields.

csharp
// ...
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; }
}
// ...
vb
Public Class CompanyPublicInfo
    Public Property CompanyName() As String
    Public Property Country() As String
    Public Property City() As String
    Public Property Url() As String
    Public Property Email() As String
    Public Property Phone() As String
    Public Property AdditionalInfo() As String
End Class

The GridSampleDataList class defined later in this file provides 3 methods: GetCompanyPrivateInfo, GetCompanyPublicInfo, and GetProductSample. Each of these methods returns a BindingList populated with objects of corresponding classes:

csharp
public class GridSampleDataList {
    static public List<CompanyPublicInfo> GetCompanyPublicInfo() {
        return new List<CompanyPublicInfo> {
                new CompanyPublicInfo() {
                    AdditionalInfo = "Some Info",
                    City = "Glendale",
                    CompanyName = "Developer Express",
                    Country = "USA",
                    Email = "[email protected]",
                    Phone = "1234567890",
                    Url = "www.devexpress.com",
                },
                // ...
            };
    }
    // ...
}
vb
Public Class GridSampleDataList
    Public Shared Function GetCompanyPublicInfo() As List(Of CompanyPublicInfo)
        Return New List(Of CompanyPublicInfo) From {
            New CompanyPublicInfo() With {
                .AdditionalInfo = "Some Info",
                .City = "Glendale",
                .CompanyName = "Developer Express",
                .Country = "USA",
                .Email = "[email protected]",
                .Phone = "1234567890",
                .Url = "www.devexpress.com"
            }
        }
    End Function
    ' ...
End Class

Now create the UI allowing application users to switch between these three data sources. Return to the main form design where you can see the editor added to the Ribbon Control. The dropdown list will have three items corresponding to data source types defined earlier.

Now handle the BarEditItem.EditValueChanged event to assign different BindingList objects to the grid’s GridControl.DataSource depending on the currently selected dropdown list item.

csharp
private void barEditItem1_EditValueChanged(object sender, EventArgs e) {
    DevExpress.XtraBars.BarEditItem item = sender as DevExpress.XtraBars.BarEditItem;
    if(item == null) return;
    switch (item.EditValue as string) {
        case "Company public info":
            gridControl.DataSource = GridSampleDataList.GetCompanyPublicInfo();
            break;
        case "Company private info":
            gridControl.DataSource = GridSampleDataList.GetCompanyPrivateInfo();
            break;
        case "Product info":
            gridControl.DataSource = GridSampleDataList.GetProductSample();
            break;
    }
}
vb
Private Sub barEditItem1_EditValueChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim item As DevExpress.XtraBars.BarEditItem = TryCast(sender, DevExpress.XtraBars.BarEditItem)
    If item Is Nothing Then
        Return
    End If
    Select Case TryCast(item.EditValue, String)
        Case "Company public info"
            gridControl.DataSource = GridSampleDataList.GetCompanyPublicInfo()
        Case "Company private info"
            gridControl.DataSource = GridSampleDataList.GetCompanyPrivateInfo()
        Case "Product info"
            gridControl.DataSource = GridSampleDataList.GetProductSample()
    End Select
End Sub

To make sure that grid columns are re-created based on the currently available data fields, handle the GridControl.DataSourceChanged event that fires each time the grid receives a new data source. In the event handler, simply call the ColumnView.PopulateColumns method that does exactly what is needed.

csharp
void gridControl_DataSourceChanged(object sender, EventArgs e) {
    DevExpress.XtraGrid.GridControl grid = sender as DevExpress.XtraGrid.GridControl;
    if(grid == null) return;
    grid.MainView.PopulateColumns();
    (grid.MainView as GridView).BestFitColumns();
}
vb
Private Sub gridControl_DataSourceChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim grid As DevExpress.XtraGrid.GridControl = TryCast(sender, DevExpress.XtraGrid.GridControl)
    If grid Is Nothing Then
        Return
    End If
    grid.MainView.PopulateColumns()
    TryCast(grid.MainView, GridView).BestFitColumns()
End Sub

Run the application to see how this works. The application still starts with auto-generated sample data. If you select an item from the dropdown list in the Ribbon, the grid will display data from the corresponding data source.

Applying Data Annotation Attributes

Notice that all grid columns are displayed with their default editors and have default formatting applied. For instance, the Product Info data contains multi-line text that cannot be viewed entirely since the default grid cell editor allows only single-line text. Company Public Info data includes URLs and e-mails that are displayed as simple text strings, as well as phone numbers that should ideally use a phone mask format. Finally, the Private Company Info displays passwords that should not be immediately visible.

One way to change this is by accessing column objects and updating their settings. But that would mean that you should do this every time you bind your data source to a data-aware control. Another way to do this is by using Data Annotation Attributes provided by Microsoft and supported by most DevExpress data-aware controls. To be able to use these attributes, make sure your application references the System.ComponentModel.DataAnnotations namespace.

There are two ways to use these attributes. The first and simplest method is to define required attributes before each data field. This is what is done for the Product class. Some attributes indicate data types so that an appropriate cell editor can be assigned. The ReadOnly attribute allows you to disable data editing for a specific field. You can also apply data input validation rules, as it is done by the Range attribute.

csharp
using System.ComponentModel.DataAnnotations;

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; }
}
vb
Imports System.ComponentModel.DataAnnotations

Public Class Product
    <[ReadOnly](True)>
    Public Property UnitPrice() As Double
    <EnumDataType(GetType(ProductCategory))>
    Public Property Category() As Integer
    <Display(Description := "The amount of currently available product")>
    Public Property Quantity() As Integer
    <DataType(DataType.Text), Display(Order := -1)>
    Public Property Text() As String
    <DataType(DataType.MultilineText)>
    Public Property MultilineText() As String
    <DataType(DataType.Currency), Range(200, 5000)>
    Public Property Currency() As Integer
    <DataType(DataType.Date)>
    Public Property Date As Date
    <DataType(DataType.Time)>
    Public Property Time() As Date
End Class

Launch the app and switch to the Product Info data to see how it looks now. The multiline text uses the MemoEdit cell editor that allows us to view the text entirely, and the Currency column allows only data in the specified range.

This approach is most useful when you have unique data fields that are not used in multiple classes. Another way to accomplish the same task is by using the MetadataType class attribute. Using this approach, you can define a data field attribute once and then use the definition for multiple classes. It can also improve code readability, since data attributes don’t have to precede every property definition.

Both Private and Public Company Info classes will use metadata defined by the CompanyProductMetadata class.

csharp
[MetadataType(typeof(CompanyProductMetadata))]
public class CompanyPublicInfo {
    // ...
}

// ...

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;
    // ...
}
vb
<MetadataType(GetType(CompanyProductMetadata))>
Public Class CompanyPublicInfo
    ' ...
End Class

Public Class CompanyProductMetadata
    <Display(ShortName := "Company", Name := "Company Name", AutoGenerateFilter := False)>
    Public CompanyName As Object
    <Display(Order := 2)>
    Public Country As Object
    <Display(Order := 1), Editable(False)>
    Public City As Object
    <DataType(DataType.Url)>
    Public Url As Object
    <DataType(DataType.EmailAddress)>
    Public Email As Object
    <DataType(DataType.PhoneNumber), Required>
    Public Phone As Object
    <DataType(DataType.Text), Display(Order := -1)>
    Public Text As Object
    <Display(AutoGenerateField := False, Description := "This column isn't created")>
    Public AdditionalInfo As Object
    <DataType(DataType.Password), StringLength(20, MinimumLength := 3)>
    Public Password As Object
    ' ...
End Class

Run the application to see the result. Switch to the Public Company Info data source to see that URLs are now displayed as actual hyperlinks and phone numbers use masked input.

Complete Code

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.

View Example

csharp
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 = "[email protected]",
                            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,
                        }
                    };
        }
    }
}
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;

namespace GridDataAttributes {
    public partial class Form1 : XtraForm {
        public Form1() {
            InitializeComponent();
            gridView1.OptionsView.ShowGroupPanel = false;
            gridControl1.DataSourceChanged += gridControl1_DataSourceChanged;
        }

        void gridControl1_DataSourceChanged(object sender, EventArgs e) {
            gridControl1.MainView.PopulateColumns();
            (gridControl1.MainView as GridView).BestFitColumns();
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            //gridControl1.DataSource = CompanyProductList.GetSampleData();
            //companyProductListBindingSource.DataSource = CompanyProductList.GetSampleData();
            //companyProductBindingSource.DataSource = CompanyProductList.GetSampleData();
        }

        private void barEditItem3_EditValueChanged(object sender, EventArgs e) {
            switch (barEditItem3.EditValue as string) {
                case "Company public info":
                    gridControl1.DataSource = GridSampleDataList.GetCompanyPublicInfo();
                    break;
                case "Company private info":
                    gridControl1.DataSource = GridSampleDataList.GetCompanyPrivateInfo();
                    break;
                case "Product info":
                    gridControl1.DataSource = GridSampleDataList.GetProductSample();
                    break;
            }
        }
    }
}
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.Skins;

namespace GridDataAttributes {
    static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            SkinManager.EnableFormSkins();
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
vb
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading.Tasks
Imports System.Windows.Forms
Imports DevExpress.Skins

Namespace GridDataAttributes
    Friend NotInheritable Class Program

        Private Sub New()
        End Sub

        ''' <summary>
        ''' The main entry point for the application.
        ''' </summary>
        <STAThread> _
        Shared Sub Main()
            SkinManager.EnableFormSkins()
            Application.EnableVisualStyles()
            Application.SetCompatibleTextRenderingDefault(False)
            Application.Run(New Form1())
        End Sub
    End Class
End Namespace
vb
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows.Forms
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Views.Grid

Namespace GridDataAttributes
    Partial Public Class Form1
        Inherits XtraForm

        Public Sub New()
            InitializeComponent()
            gridView1.OptionsView.ShowGroupPanel = False
            AddHandler gridControl1.DataSourceChanged, AddressOf gridControl1_DataSourceChanged
        End Sub

        Private Sub gridControl1_DataSourceChanged(ByVal sender As Object, ByVal e As EventArgs)
            gridControl1.MainView.PopulateColumns()
            TryCast(gridControl1.MainView, GridView).BestFitColumns()
        End Sub

        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
            MyBase.OnLoad(e)
            'gridControl1.DataSource = CompanyProductList.GetSampleData();
            'companyProductListBindingSource.DataSource = CompanyProductList.GetSampleData();
            'companyProductBindingSource.DataSource = CompanyProductList.GetSampleData();
        End Sub

        Private Sub barEditItem3_EditValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles barEditItem3.EditValueChanged
            Select Case TryCast(barEditItem3.EditValue, String)
                Case "Company public info"
                    gridControl1.DataSource = GridSampleDataList.GetCompanyPublicInfo()
                Case "Company private info"
                    gridControl1.DataSource = GridSampleDataList.GetCompanyPrivateInfo()
                Case "Product info"
                    gridControl1.DataSource = GridSampleDataList.GetProductSample()
            End Select
        End Sub
    End Class
End Namespace
vb
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks

Namespace GridDataAttributes
    <MetadataType(GetType(CompanyProductMetadata))> _
    Public Class CompanyPublicInfo
        Public Property CompanyName() As String
        Public Property Country() As String
        Public Property City() As String
        Public Property Url() As String
        Public Property Email() As String
        Public Property Phone() As String
        Public Property AdditionalInfo() As String
    End Class

    <MetadataType(GetType(CompanyProductMetadata))> _
    Public Class CompanyPrivateInfo
        Public Property Password() As String
        Public Property Date2() As Date
        Public Property Sales() As Double
        Public Property Profit() As Double
        Public Property SalesVsTarget() As Double
        Public Property MarketShare() As Double
        Public Property CustomersSatisfaction() As Double
    End Class

    Public Class Product
        <[ReadOnly](True)> _
        Public Property UnitPrice() As Double
        <EnumDataType(GetType(ProductCategory))> _
        Public Property Category() As Integer
        <Display(Description := "The amount of currently available product")> _
        Public Property Quantity() As Integer
        <DataType(DataType.Text), Display(Order := -1)> _
        Public Property Text() As String
        <DataType(DataType.MultilineText)> _
        Public Property MultilineText() As String
        <DataType(DataType.Currency), Range(200, 5000)> _
        Public Property Currency() As Integer
        <DataType(DataType.Date)> _
        Public Property Date As Date
        <DataType(DataType.Time)> _
        Public Property Time() As Date
    End Class

    Public Class CompanyProductMetadata
        <Display(ShortName := "Company", Name := "Company Name", AutoGenerateFilter := False)> _
        Public CompanyName As Object
        <Display(Order := 2)> _
        Public Country As Object
        <Display(Order := 1), Editable(False)> _
        Public City As Object
        <DataType(DataType.Url)> _
        Public Url As Object
        <DataType(DataType.EmailAddress)> _
        Public Email As Object
        <DataType(DataType.PhoneNumber), Required> _
        Public Phone As Object
        <DataType(DataType.Text), Display(Order := -1)> _
        Public Text As Object
        <Display(AutoGenerateField := False, Description := "This column isn't created")> _
        Public AdditionalInfo As Object
        <DataType(DataType.Password), StringLength(20, MinimumLength := 3)> _
        Public Password As Object
        <DisplayFormat(DataFormatString := "MMMM/yyyy"), Display(Name := "Date 2")> _
        Public Date2 As Object
        <DisplayFormat(DataFormatString := "#,##0,,M")> _
        Public Sales As Object
        <DisplayFormat(DataFormatString := "#,##0,,M")> _
        Public Profit As Object
        <DisplayFormat(DataFormatString := "p", ApplyFormatInEditMode := True), Display(Name := "Sales vs Target")> _
        Public SalesVsTarget As Object
        <DisplayFormat(DataFormatString := "p0", ApplyFormatInEditMode := False)> _
        Public MarketShare As Object
        <Display(Name := "Cust Satisfaction")> _
        Public CustomersSatisfaction As Object
    End Class

    Public Enum ProductCategory
        Beverages = 1
        Fruit = 2
        Vegetables = 3
        Meat = 4
        Condiments = 5
        Confections = 6
        DairyProducts = 7
        GrainsCereals = 8
        Seafood = 9
    End Enum

    Public Class GridSampleDataList
        Public Shared Function GetCompanyPrivateInfo() As List(Of CompanyPrivateInfo)
            Return New List(Of CompanyPrivateInfo) From { _
                New CompanyPrivateInfo() With {.CustomersSatisfaction = 3.1, .Date2 = Date.Now, .MarketShare = 42, .Password = "123qwerty", .Profit = 4951515, .Sales = 311414134, .SalesVsTarget = 0.0277} _
            }
        End Function
        Public Shared Function GetCompanyPublicInfo() As List(Of CompanyPublicInfo)
            Return New List(Of CompanyPublicInfo) From { _
                New CompanyPublicInfo() With {.AdditionalInfo = "Some Info", .City = "Glendale", .CompanyName = "Developer Express", .Country = "USA", .Email = "[email protected]", .Phone = "1234567890", .Url = "www.devexpress.com"} _
            }
        End Function
        Public Shared Function GetProductSample() As List(Of Product)
            Return New List(Of Product) From { _
                New Product() With {.Currency = 1000, .Category = 2, .Date = Date.Now, .MultilineText = "Line1" & ControlChars.CrLf & "Line2" & ControlChars.CrLf & "Line3", .Quantity = 321, .Text = "Sample Text", .Time = Date.Now, .UnitPrice = 1800} _
            }
        End Function
    End Class
End Namespace