2009-09-10 8 views
0

J'utilise C#, Windows Forms, .NET 3.5 SP1DataGridView avec des colonnes d'exécution

J'ai un DataGridView avec beaucoup de colonnes que je ne sais pas avant l'exécution du temps (je don Je sais que j'ai besoin d'une colonne Foo jusqu'à l'exécution). Pour obtenir des données dans et hors des cellules, je pense à l'architecture suivante. Suis-je sur la bonne voie, ou est-ce qu'il me manque quelque chose de plus facile?

public interface ICustomColumn 
{ 
    object Format (DataGridView dgv, DataGridViewCellFormattingEventArgs e); 
    void Validate (DataGridView dgv, DataGridViewCellValidatingEventArgs e); 
} 

public class CustomDataGridView : DataGridView 
{ 
    protected override void OnCellFormatting (DataGridViewCellFormattingEventArgs e) 
    { 
     ICustomColumn col = Columns [e.ColumnIndex].Tag as ICustomColumn; 
     if (col != null) 
      e.Value = col.Format (this, e); 

     base.OnCellFormatting (e); 
    } 

    protected override void OnCellValidating (DataGridViewCellValidatingEventArgs e) 
    { 
     ICustomColumn col = Columns [e.ColumnIndex].Tag as ICustomColumn; 
     if (col != null) 
      col.Validate (this, e); 

     base.OnCellValidating (e); 
    } 
} 

class FooColumn : ICustomColumn 
{ 
    public FooColumn (Dictionary <RowData, Foo> fooDictionary) 
     { this.FooDictionary = fooDictionary; } 

    // Foo has a meaningful conversion to the column type (e.g. ToString() for a text column 
    protected object Format (DGV dgv, DGVCFEA e) 
     { return FooDictionary [(RowData) dgv.Rows[e.RowIndex].DataBoundItem]; } 

    // Foo has a meaningful way to interpret e.FormattedValue 
    void Validate (DGV dgv, DGVCVEA e) 
     { FooDictionary [(RowData) dgv.Rows[e.RowIndex].DataBoundItem].Validate (e.FormattedValue); } 
} 

void CreateFooColumn (DataGridView dgv) 
{ 
    dgv.Columns.Add (new DataGridViewTextBoxColumn() { Tag = new FooColumn (fooDictionary) }); 
} 

Répondre

1

Une autre approche consisterait à utiliser la réflexion.

Pour configurer le DataGridView:

private void SetUpDataGridView() 
{ 
    // Create the columns based on the data in the album info - get by reflection 
    var ai = new AlbumInfo(); 
    Type t = ai.GetType(); 

    dataTable.TableName = t.Name; 

    foreach (PropertyInfo p in t.GetProperties()) 
    { 
     var columnSpec = new DataColumn(); 
     // If nullable get the underlying type 
     Type propertyType = p.PropertyType; 
     if (IsNullableType(propertyType)) 
     { 
      var nc = new NullableConverter(propertyType); 
      propertyType = nc.UnderlyingType; 
     } 
     columnSpec.DataType = propertyType; 
     columnSpec.ColumnName = p.Name; 
     dataTable.Columns.Add(columnSpec); 
    } 
} 

La méthode d'assistance:

private bool IsNullableType(Type theType) 
{ 
    return (theType.IsGenericType && 
      theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))); 
} 

pour alimenter le DataGridView:

private void AddToGrid(AlbumInfo info) 
{ 
    // Add album info to table - add by reflection 
    Type t = info.GetType(); 
    var row = new object[t.GetProperties().Length]; 

    int index = 0; 
    foreach (PropertyInfo p in t.GetProperties()) 
    { 
     row[index++] = p.GetValue(info, null); 
    } 

    dataTable.Rows.Add(row); 
    dataGridView.ClearSelection(); 
} 
Questions connexes