DataGridView-использование DataPropertyName для отображения свойства дочернего элемента

позволяет изображение, что у меня есть следующие классы

public class Master
{
    public string MasterName = "Something";

    public List<Detail> details = new List<Detail>();
}

public class Detail 
{
    public string Foo = "Test";
}

и затем я хочу показать коллекцию объектов Details в DataGridView, используя код ниже

DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "Details.Foo";
column.HeaderText = "Foo header";

dgv.Columns.Add(column);

столбец отображается в сетке, но без значения

5 ответов


вы можете переопределить метод ToString в дочернем объекте сущности, например:

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;
    }

и позже свяжите дочернее имя сущности.


Если вам нужно быть более общим (т. е. использовать DataPropertyName = "MyProp1.MyProp2.MyProp3") вы можете использовать этот

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;
    }
}

в случае, если вы хотите использовать много дочерних элементов как это:

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

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

Как насчет:

1-й раствор Установите значение для каждой ячейки в каком-либо событии (mabye другое лучше), вручную, после установки источника данных, например:

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;
}

2 раствор Как насчет создания правильного DataTable из данных, а затем просто привязать его?

Я был бы благодарен за любые мнения ;-)


просто сделать это:

маскируйте свойство, из которого вы хотите получить childvalue с помощью [Browsable(false)], чтобы оно не отображалось в datagrid. Затем создайте новое свойство в своем классе, которое содержит дочерний объект, который имеет только метод "get", показывающий значение childproperty: Например:

[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;

где ваш datasoure? вы должны привести к источнику. что он найдет его. вы можете сделать это

источник :

  1. :

    List<Detail> list = new List<Detail>();
    for (int i = 0; i < 10; i++)
    {
         Detail d = new Detail();
         d.Foo = "test";
         list.Add(d);
    }
    
    this.dgv.DataSource = list;
    this.dgv.Columns[0].Visible = false;
    DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
    dgvc.HeaderText = "列标题";
    dgvc.DataPropertyName = "foo";
    this.dgv.Columns.Add(dgvc);
    
  2. :

    public class Detail
    {
         private string foo;
    
         public string Foo
         {
             get { return foo; }
             set { foo = value; }
         }
     }