让我有以下类的图像
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);
列显示在网格中,但没有值
答案 0 :(得分:11)
如果您需要更通用(即使用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;
}
}
答案 1 :(得分: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然后绑定它呢?
我会感激任何意见; - )
答案 2 :(得分:2)
您可以在实体子代中覆盖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;
}
然后绑定实体子名称。
答案 3 :(得分:1)
这样做:
使用[Browsable(false)]屏蔽要获取子值的属性,以便它不会显示在datagrid中。 然后在您的类中创建一个NEW属性,该属性包含只有&#34; get&#34;显示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;
答案 4 :(得分:0)
您的数据来源在哪里?你必须导致来源。它会找到它。 你可以这样做
来源:
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);
public class Detail
{
private string foo;
public string Foo
{
get { return foo; }
set { foo = value; }
}
}
答案 5 :(得分:0)
bubi's answer很棒。我添加了一个小调整,如果您使用的是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;
}