DataGridView - Use DataPropertyName to show child element property
Just do this:
Mask the property you want to get a childvalue from with [Browsable(false)] so it wont show up in the datagrid. Then create a NEW property in your class that holds the child object which has only a "get" method showing the childproperty value: For example:
[Browsable(false)] //Because we use the CreatorUsernameProperty to do this.
public virtual User Creator { get; set; }
[DisplayName("Creator")] //shows like this in the grid
public string CreatorUsername => Creator?.Username;
If you need to be more generic (i.e. using DataPropertyName = "MyProp1.MyProp2.MyProp3"
) you can use this
private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewColumn column = Grid.Columns[e.ColumnIndex];
if (column.DataPropertyName.Contains("."))
{
object data = Grid.Rows[e.RowIndex].DataBoundItem;
string[] properties = column.DataPropertyName.Split('.');
for (int i = 0; i < properties.Length && data != null; i++)
data = data.GetType().GetProperty(properties[i]).GetValue(data);
Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = data;
}
}
In case you want to use many child elements like this:
class MyClass
{
public int Id;
public MyOtherClass OtherClass;
}
class MyOtherClass
{
public string Name;
public int Number;
}
How about:
1st solution Set value for each cell in some event (mabye another one is better), manually, after setting datasource, for example:
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;
}
2nd solution What about creating proper DataTable from the data and then just bind it?
I'd be thankful for any opinion ;-)
You can override ToString method in the entity child for example:
public class FormulariosENT {
#region PROPERTIES
public int IdFromulario { get; set; }
public string DescripcionFormulario { get; set; }
#endregion
#region PUBLIC METHODS
public override string ToString() {
return DescripcionFormulario;
}
And later bind the entity child name.