![](/img/trans.png)
[英]Related many to one navigation properties not loading with EF code first
[英]EF, WinForms: how to add related navigation properties to DataGridView?
我的數據庫中有User和UserGroup表:
我按照本教程http://msdn.microsoft.com/en-us/data/jj682076.aspx生成了EF模型(首先是數據庫)和用戶數據源。
在我的表單上,我創建了BindingSource(bsUsers)並將其綁定到DataGridView,因此它顯示了ID和用戶名。
這是我在表單啟動時加載數據的方式:
_myDbContext = new MyDbContext();
_myDbContext.Users.Load();
bsUsers.DataSource = _myDbContext.Users.Local.ToBindingList();
但是現在我想在同一DataGridView中顯示GroupName。 最好的方法是什么?
我嘗試僅在DataPropertyName
列中指定UserGroup.GroupName
,但是它不起作用,單元格保持為空。
到目前為止,我發現的唯一解決方案是創建一個新的未綁定列並手動填充它:
foreach (var item in (IList<User>)bsUsers.DataSource)
{
dgw.Rows[i].Cells["GroupName"].Value = item.UserGroup.Name;
}
但這似乎不是一個好方法。 例如,在更改用戶組之后,我將需要再次更新它,或者在添加新記錄時。
找到了更好的方法: 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);
}
您可以簡單地在模型中重寫ToString()。 即使我強烈建議使用ViewModel。
public class UserGroup{
public int Id { get; set; }
public string GroupName { get; set; }
public override string ToString() {
return GroupName;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.