views:

26

answers:

1

I have dynamically created DataGridView control on form, with DataSource specified as:

    ((DataGridView)createdControl).DataSource = (IList)(p.GetValue(editedClient, null));

where IList is defined as generic collection for following class:

     public class CDocumentOperation

   {
        [DisplayName(@"Time")] 
        public DateTime TimePosted { get; set; }
        [DisplayName(@"User")]
        public CUser User { get; set; }
        [DisplayName(@"Action")]
        public string Action { get; set; }
    }

grid is populated successfully with data, but the only problem that all columns are created as Text fields.What I need is to manually convert column which binds to User field, to have Buttons or Links (convert column type to DataGridViewButtonColumn).

Can I do this, without modifying grid auto-fill on grid post creation, without manual column creation of appropriate type and data copying ?

A: 

The short answer is that this cannot be done without manually creating the columns (and setting the DataPropertyName property) before binding. There is no attribute you can use to decorate your data source, the DataGridView will simply generate a DataGridViewTextBoxColumn for every data type (except Boolean which it will resolve to a checkbox column). This behaviour is internal and unchangeable.

Your best bet is to disable AutoGenerateColumns on the grid and write your own method that dynamically generates appropriate column types, perhaps based on your own custom attribute, such as (from your example above):

[DisplayName(@"Time"), ColumnType(typeof(DataGridViewButtonColumn))] 
public DateTime TimePosted { get; set; }

The attribute class is easy to write (just extend Attribute, add a Type field and an appropriate constructor). In the method that will generate the columns (immediately before binding), you can use reflection to crawl for properties and check for the presence of the custom attribute. (BindingSource.GetItemProperties() is very useful for obtaining information about the properties on objects in a collection.)

This is not the most elegant solution (and it delves into some intermediate-level concepts), but it's the only way to get around this limitation with auto-generated columns in the DataGridView control.

Bradley Smith