Set Format of auto-generated columns in DataGridView having object DataSource

后端 未结 1 1405
独厮守ぢ
独厮守ぢ 2021-01-22 19:47

I would like to auto create all the columns for my DataGridView based on my custom class. Every thing works like it should, but what I need is to format and align t

相关标签:
1条回答
  • 2021-01-22 20:16

    Using custom attributes to control appearance of DataGridView columns

    When auto-generating columns in DataGridView, there is built-in support for a few attributes including ReadOnly, DisplayName and Browsable attribute. For example, if you mark a property using Browsable(false) it will not be added as a column to DataGridView.

    But for Format, there is no such built-in support. You can create a custom DisplayFormat attribute and write some code to use it in DataGridView after auto generating columns.

    For example, let's say you have a class like this:

    using System;
    using System.ComponentModel;
    public class Product
    {
        [DisplayName("Code")]
        [Description("Unique code of the product")]
        public int Id { get; set; }
    
        [DisplayName("Product Name")]
        [Description("Name of the product")]
        public string Name { get; set; }
    
        [DisplayName("Unit Price")]
        [Description("Unit price of the product")]
        [DisplayFormat("C2")]
        public double Price { get; set; }
    }
    

    And as a result, we are going to have a DataGridView like the screenshot, which can see we used the value of Description attribute as tooltip text for columns and also we used DisplayFormat to show the price in currency format:

    First we should create the custom attribute for format, DisplayFormat:

    using System;
    using System.ComponentModel;
    public class DisplayFormatAttribute : Attribute
    {
        public DisplayFormatAttribute(string format)
        {
            Format = format;
        }
        public string Format { get; set; }
    }
    

    Then load data and auto generate columns, for example:

    var list = new List<Product>() {
        new Product(){ Id=1, Name="Product 1", Price= 321.1234},
        new Product(){ Id=2, Name="Product 2", Price= 987.5678},
    };
    this.dataGridView1.DataSource = list;
    

    Then to take advantage of attributes, you can write such code which is not dependent to the model type:

    var type = ListBindingHelper.GetListItemType(dataGridView1.DataSource);
    var properties = TypeDescriptor.GetProperties(type);
    foreach (DataGridViewColumn column in dataGridView1.Columns)
    {
        var p = properties[column.DataPropertyName];
        if (p != null)
        {
            var format = (DisplayFormatAttribute)p.Attributes[typeof(DisplayFormatAttribute)];
            column.ToolTipText = p.Description;
            column.DefaultCellStyle.Format = format == null ? null : format.Format;
        }
    }
    

    You can simply encapsulate above code in a method like void SetupColumn(DataGridView dgv) or if you have a derived DataGridView, you can create a DataBind(object data) method and in the method, assign data to DataSource and then use above code as rest of body of the method.

    Note

    I also read in the comments under your question that you have told '...for each field is a bit much.' If for any reason you don't like the attribute approach, you can simply stick to a for loop like this:

    foreach (DataGridViewColumn c in dataGridView1.Columns)
    {
        if (c.ValueType == typeof(double))
        {
            c.DefaultCellStyle.Format = "C2";
            c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        }
    }
    

    DataAnnotations attributes for in Windows Forms

    To see how can you use data annotations attribute in Windows Forms for DataGridView and also for Validation, take a look at these posts:

    • DataAnnotations attributes for DataGridView in Windows Forms
    • DataAnnotations Validation attributes for Windows Forms
    0 讨论(0)
提交回复
热议问题