13

让我们想象一下我有以下课程

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

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

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

然后我想在 DataGridView 中显示 Details 对象的集合,使用下面的代码

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

dgv.Columns.Add(column);

该列显示在网格中,但没有值

4

6 回答 6

14

如果您需要更通用(即使用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;
    }
}
于 2016-03-08T09:05:26.523 回答
4

您可以覆盖实体子实体中的 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;
    }

然后绑定实体子名。

于 2013-04-18T01:00:46.333 回答
4

如果您想使用许多这样的子元素:

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

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

怎么样:

第一种解决方案 在某些事件中为每个单元格设置值(也许另一个更好),在设置数据源之后手动设置,例如:

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

第二种解决方案 如何从数据创建适当的 DataTable 然后绑定它?

我会感谢任何意见;-)

于 2015-10-07T10:02:34.663 回答
4

只需这样做:

使用 [Browsable(false)] 屏蔽要从中获取子值的属性,使其不会显示在数据网格中。然后在您的类中创建一个新属性,该属性包含仅具有显示子属性值的“get”方法的子对象:例如:

[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;
于 2017-08-05T13:27:01.807 回答
0

你的数据源在哪里?你必须导致源。它会找到它。你可以这样做

来源 :

  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; }
         }
     }
    
于 2012-12-27T03:32:13.343 回答
0

bubi 的回答很棒。如果您使用的是BindingListView ,我添加了一个小调整,让该方法起作用。

编辑:此方法禁用对通过子属性定位的列的排序。目前不知道如何解决这个问题。

if (column.DataPropertyName.Contains("."))
{
    object data = dgv.Rows[e.RowIndex].DataBoundItem;
    if (data is ICustomTypeDescriptor ictd) // support BindingListView
        data = ictd.GetPropertyOwner(null);
    string[] properties = column.DataPropertyName.Split('.');
    for (int i = 0; i < properties.Length && data != null; i++)
    data = data.GetType().GetProperty(properties[i])?.GetValue(data);
    e.Value = data;
}
于 2019-05-22T15:10:42.210 回答