C# WinForm DataGridView让DataPropertyName支持复杂属性
首先给Grid添加BindingSource,类型为BindingForForm2。或者设置Grid的DataSource为IEnumerable<BindingForForm2>。
BindingForForm2类型如下。
public class BindingForForm2 { public int Age { get; set; } public string Name { get; set; } public int Height { get; set; } public int Weight { get; set; } public ClassTest ClassTest { get; set; } } public class ClassTest { public string S1 { get; set; } public string S2 { get; set; } }
我们想在Grid上直接显示BindingForForm2中ClassTest属性的S1和S2属性。可以如下图设置DataPropertyName。直接设置用属性点的方式。
然后如下注册DataGridView的CellFormatting事件即可。代码大致意思是,先取到当前选中行的Object(此处为BindingForForm2),然后取到DataPropertyName的设置,再循环用反射读取想要的值。
1 private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 2 { 3 if (e.Value != null) return; 4 try 5 { 6 var dgv = (DataGridView)sender; 7 object obj = null; 8 var source = dgv.DataSource as BindingSource; 9 if (source != null) 10 { 11 obj = ((IEnumerable<object>)source.DataSource).ElementAt(e.RowIndex); 12 } 13 else if (dgv.DataSource is IEnumerable<object>) 14 { 15 obj = ((IEnumerable<object>)dgv.DataSource).ElementAt(e.RowIndex); 16 } 17 var col = dgv.Columns[e.ColumnIndex]; 18 var props = col.DataPropertyName.Split('.'); 19 foreach (var prop in props) 20 { 21 if (obj == null) return; 22 var p = obj.GetType().GetProperty(prop); 23 if (p == null) return; 24 obj = p.GetValue(obj, null); 25 } 26 e.Value = obj; 27 } 28 catch 29 { 30 //ignore 31 } 32 }
效果:
bindingSource填充数据
bindingForForm2BindingSource.DataSource = new List<BindingForForm2> { new BindingForForm2 {Age = 10, Height = 120, Name = "xxx", ClassTest = new ClassTest {S1 = "sdjfkljlk"}}, new BindingForForm2 {Age = 12, Height = 120, Name = "asd", ClassTest = new ClassTest {S2 = "ccccccc"}}, new BindingForForm2 {Age = 14, Height = 120, Name = "asdd"} };
GridView显示