2010-02-08 29 views
7

Tengo un control DataGridView y quiero rellenarlo con datos.DataGridViewColumn.DataPropertyName Propiedad

utilizo propiedad DataSource

// dgvDealAsset is DataGridView 
     private void DealAssetListControl_Load(object sender, EventArgs e) 
     { 
      dgvDealAssets.AutoGenerateColumns = false; 
      dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList(); 
} 

Ahora el problema número uno. La clase de mi colección no contiene solo tipos simples que puedo asignar a columnas usando DataPropertyName. Esta es la clase que está contenida en la colección.

class MyClass 
{ 
    public String Name; 
    MyOtherClass otherclass; 
} 

class MyOtherClass 
{ 
public String Name; 
} 

Ahora estoy propiedades de unión a MiClase columnas

col1.DataPropertyName = "Name" // Ok 
col2.DataPropertyName = "otherclass" // Not OK - I will have empty cell 

El problema es que quiero mostrar otherclass.Name campo. Pero si trato de escribir

col2.DataPropertyName = "otherclass.Name" 

Me sale la celda vacía.

Me trataron de ajustar manualmente la columna

private void DealAssetListControl_Load(object sender, EventArgs e) 
{ 
    dgvDealAssets.AutoGenerateColumns = false; 
    dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList(); 

// iterate through rows and set the column manually 
     foreach (DataGridViewRow row in dgvDealAssets.Rows) 
     { 
      row.Cells["Column2"].Value = ((DealAsset)row.DataBoundItem).otherclass.Name; 
     } 

Pero este ciclo foreach tarda unos minutos para completar 2k (elementos). ¿Cómo resolver este problema?

Respuesta

3

DataGridView no admite enlace de datos a propiedades secundarias. Para obtener más información, consulte this post

Me gusta la solución que utiliza el evento CellFormatting.

2

Problema nº1:

tratar de hacer lo siguiente:

  1. extender MyOtherClass del objeto (no podría ser necesario este paso)

  2. y anulación, o crear , método ToString().

Eso debería hacerlo.

+0

No se puede hacer. Este es un objeto de biblioteca de terceros. –

+0

Si MyOtherClass no está sellado a continuación, intente esto: MyOtherClass2 clase: MyOtherClass { public String toString() { /* cadena de retorno aquí, que desea que aparezca en la red */ } } – user218447

1

Parece que el modo virtual del DataGridView resolvería su problema. En modo virtual, DataGridView disparará un evento cada vez que necesite mostrar una celda. El evento te permite poblar la celda como desees. La ventaja del modo virtual es que el sistema solo necesita extraer los datos que realmente se muestran, por lo que no hay un tiempo de inicio lento mientras carga todo.

private void my_init_function() { 
     datagridview.VirtualMode = true; 
     datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded); 
    } 

    private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) 
    { 
     e.Value = get_my_data(e.RowIndex, e.ColumnIndex); 
    } 
3

En caso de que quiera utilizar muchos elementos secundarios como esto:

class MyClass 
{ 
    public int Id; 
    public MyOtherClass OtherClass; 
} 

class MyOtherClass 
{ 
    public string Name; 
    public int Number; 
} 

¿Qué tal

primera solución valor Conjunto para cada célula en algún evento (mabye otro es mejor), manualmente, después de establecer el origen de datos, por ejemplo:

private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    MyClass data = dgv.Rows[ e.RowIndex ].DataBoundItem as MyClass; 

    dgv.Rows[ e.RowIndex ].Cells[ "colName" ].Value = data.OtherClass.Name; 
    dgv.Rows[ e.RowIndex ].Cells[ "colNumber" ].Value = data.OtherClass.Number; 
} 

segunda solución ¿Qué tal crear una DataTable a partir de los datos y luego vincularla?

Estaría agradecido por cualquier opinión ;-)

+0

Este es el ¡respuesta correcta! Muchas gracias! –

1

La forma de enlace de datos de una columna específica de una cuadrícula de datos a una propiedad secundaria de la fuente de datos de la cuadrícula de datos está utilizando la propiedad DataGridView.Column.Tag, junto con el método de invalidación dentro ToString() el objeto niño. Va de la siguiente manera:

public class Car 
{ 
    public int Id { get; set; } 

    public int Name { get; set; } 

    public string Colour { get; set; } 

    public Wheel Wheel { get; set; } 
} 

public class Wheel 
{ 
    public string WheelName { get; set; } 

    public override string ToString() 
    { 
     return WheelName; 
    } 
} 

public class Main 
{ 
    private void LoadGrid(List<Car> data) 
    { 
     this.dataGridView.Columns["Wheel"].Tag = "WheelName"; 
    } 
}