我的数据库中有User和UserGroup表:
我按照本教程http://msdn.microsoft.com/en-us/data/jj682076.aspx
生成了EF模型(数据库优先)和DataSource for User在我的表单上,我创建了BindingSource(bsUsers)并将DataGridView绑定到它,因此它显示了Ids和Usernames。
以下是我在表单启动时加载数据的方法:
_myDbContext = new MyDbContext();
_myDbContext.Users.Load();
bsUsers.DataSource = _myDbContext.Users.Local.ToBindingList();
但是现在我想在同一个DataGridView中显示GroupName。最好的方法是什么?
我尝试在UserGroup.GroupName
列中指定DataPropertyName
,但它不起作用,单元格仍为空。
到目前为止,我找到的唯一解决方案是创建一个新的未绑定列并手动填充:
foreach (var item in (IList<User>)bsUsers.DataSource)
{
dgw.Rows[i].Cells["GroupName"].Value = item.UserGroup.Name;
}
但它看起来不是一个好方法。例如,在更改用户组后,我将需要再次更新它,或者在添加新记录时。
答案 0 :(得分:5)
找到了更好的方法: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;
}
}
在列中,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);
}
}
此外,我将ComboBox绑定到相同的BindingSource,允许更改当前所选用户的组。要更新相应DataGridView单元格中的值,我在ComboBox的SelectedIndexChanged
事件中执行此操作:
private void cbbUserGroup_SelectedIndexChanged(object sender, EventArgs e)
{
Validate();
dgwUsers.UpdateCellValue(dgwUsers.Columns["GroupName"].Index, dgwUsers.CurrentRow.Index);
}
答案 1 :(得分:0)
您可以简单地覆盖模型中的ToString()。即使我强烈建议使用ViewModel。
public class UserGroup{
public int Id { get; set; }
public string GroupName { get; set; }
public override string ToString() {
return GroupName;
}