Ale*_* P. 1 c# ado.net entity-framework datagridview winforms
我的数据库中有User和UserGroup表:

我按照本教程生成EF模型(数据库优先)和DataSource for User http://msdn.microsoft.com/en-us/data/jj682076.aspx
在我的表单上,我创建了BindingSource(bsUsers)并将DataGridView绑定到它,因此它显示了Ids和Usernames.
以下是我在表单启动时加载数据的方法:
_myDbContext = new MyDbContext();
_myDbContext.Users.Load();
bsUsers.DataSource = _myDbContext.Users.Local.ToBindingList();
Run Code Online (Sandbox Code Playgroud)
但现在我想在同一个DataGridView中显示GroupName.最好的方法是什么?
我试图UserGroup.GroupName在列中指定,DataPropertyName但它不起作用,单元格保持为空.
到目前为止,我找到的唯一解决方案是创建一个新的未绑定列并手动填充它:
foreach (var item in (IList<User>)bsUsers.DataSource)
{
dgw.Rows[i].Cells["GroupName"].Value = item.UserGroup.Name;
}
Run Code Online (Sandbox Code Playgroud)
但它看起来不是一个好方法.例如,在更改用户组后,我将需要再次更新它,或者在添加新记录时.
找到了更好的方法:http://www.developer-corner.com/blog/2007/07/19/datagridview-how-to-bind-nested-objects/(仅适用于只读,不适用于编辑) DataGridView中)
public static class BindingHelper
{
// Recursive method that returns value of property (using Reflection)
// Example: string groupName = GetPropertyValue(user, "UserGroup.GroupName");
public static object GetPropertyValue(object property, string propertyName)
{
object retValue = "";
if (propertyName.Contains("."))
{
string leftPropertyName = propertyName.Substring(0, propertyName.IndexOf("."));
PropertyInfo propertyInfo = property.GetType().GetProperties().FirstOrDefault(p => p.Name == leftPropertyName);
if (propertyInfo != null)
{
retValue = GetPropertyValue(
propertyInfo.GetValue(property, null),
propertyName.Substring(propertyName.IndexOf(".") + 1));
}
}
else
{
Type propertyType = property.GetType();
PropertyInfo propertyInfo = propertyType.GetProperty(propertyName);
retValue = propertyInfo.GetValue(property, null);
}
return retValue;
}
}
Run Code Online (Sandbox Code Playgroud)
在我DataPropertyName设置的列中UserGroup.GroupName:

而在CellFormatting事件中,我喊出了"绑定",以嵌套的属性(即具有所有列此方法.中DataPropertyName),以显示它们的值:
private void dgwUsers_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var dgw = (DataGridView) sender;
DataGridViewColumn column = dgw.Columns[e.ColumnIndex];
DataGridViewRow row = dgw.Rows[e.RowIndex];
if (column.DataPropertyName.Contains("."))
{
e.Value = BindingHelper.GetPropertyValue(row.DataBoundItem, column.DataPropertyName);
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我将ComboBox绑定到相同的BindingSource,允许更改当前所选用户的组.要更新相应DataGridView单元格中的值,我SelectedIndexChanged在ComboBox中执行此操作:
private void cbbUserGroup_SelectedIndexChanged(object sender, EventArgs e)
{
Validate();
dgwUsers.UpdateCellValue(dgwUsers.Columns["GroupName"].Index, dgwUsers.CurrentRow.Index);
}
Run Code Online (Sandbox Code Playgroud)