[英]Show Properties of a Navigation Property in DataGridView (Second Level Properties)
[英]Using ComboBox to show second-level properties in DataGridView
据我了解,ComboBox 列在 DataGridView 中的绑定比标准列更具动态性,并且这种灵活性可用于使用二阶属性中的 DisplayMembers。 这种方法是Aghaei先生在这里首次提到的。
但是,我没有做对。 我的应用程序仍然抛出“名称”不存在的异常。
public void CreateEmployeeTable()
{
DataGridViewComboBoxColumn jobTitleColumn = new DataGridViewComboBoxColumn();
jobTitleColumn.HeaderText = "Job Title";
jobTitleColumn.DataPropertyName = "JobTitle";
jobTitleColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
jobTitleColumn.DataPropertyName = "ID";
jobTitleColumn.DataSource = globalEmployeeList;
jobTitleColumn.ValueMember = "ID";
jobTitleColumn.DisplayMember = "Name";
jobTitleColumn.ReadOnly = true;
employeeGridView.AutoGenerateColumns = false;
employeeGridView.ColumnCount = 2;
employeeGridView.Columns[0].HeaderText = "Employee ID";
employeeGridView.Columns[0].DisplayIndex = 0;
employeeGridView.Columns[0].DataPropertyName = "ID";
employeeGridView.Columns[1].HeaderText = "Name";
employeeGridView.Columns[1].DataPropertyName = "ListView";
employeeGridView.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
employeeGridView.Columns.Add(jobTitleColumn);
employeeGridView.DataSource = globalEmployeeList;
}
这是 class 定义:
public class EmployeeModel
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Nickname { get; set; }
public DepartmentModel Department { get; set; }
public TitleModel JobTitle { get; set; }
public DateTime HireDate { get; set; }
public List<EmailModel> EmailList { get; set; } = new List<EmailModel>();
public List<PhoneModel> PhoneList { get; set; } = new List<PhoneModel>();
public List<RestrictionModel> RestrictionsList { get; set; } = new List<RestrictionModel>();
public List<CitationModel> CitationsList { get; set; } = new List<CitationModel>();
public List<CertificationModel> CertificationList { get; set; } = new List<CertificationModel>();
public string ListView
{
get
{
return $"{LastName}, {FirstName}";
}
}
public string ToEmailString()
{
IEnumerable<string> employeeEmailStrings = EmailList.Select(emmod => emmod.ToString());
string employeeEmailString = string.Join($"{Environment.NewLine}", employeeEmailStrings);
IEnumerable<string> certificationStrings = CertificationList.Select(clistmod => clistmod.ToString());
string certificationString = string.Join($"{Environment.NewLine}", certificationStrings);
IEnumerable<string> phoneStrings = PhoneList.Select(plistmod => plistmod.ToString());
string phoneString = string.Join($"{Environment.NewLine}", phoneStrings);
return $"{FirstName}, {LastName}: {Environment.NewLine} -{JobTitle.Name}- {Environment.NewLine} {employeeEmailString} {Environment.NewLine} {certificationString} {Environment.NewLine} {phoneString}";
}
public class EmailModel
{
public int ID { get; set; }
public string Address { get; set; }
public string Type { get; set; }
public override string ToString()
{
return $"{Address} ({Type})";
}
}
public class PhoneModel
{
public int ID { get; set; }
public string Number { get; set; }
public string Type { get; set; }
public override string ToString()
{
return $"{Number} ({Type})";
}
}
}
TitleModel 的定义:
public class TitleModel
{
public string Name { get; set; }
public int ID { get; set; }
}
}
为了支持在 DataGridView 中显示导航属性的属性(二级属性) ,我已经在同一篇文章或这个允许显示二级属性并允许编辑它们的示例中共享了一些示例。
在这里我将分享更多示例,每个示例都被编写为一个最小的完整可验证示例,您只需复制并粘贴到一个空表单中,它们就可以工作。
这些是示例:
何时:您不想更改 Employee 的JobTitle
如何:通过覆盖JobTitle
的ToString
方法
class JobTitle
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public JobTitle JobTitle { get; set; }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var jobTitles = new List<JobTitle>() {
new JobTitle {Id= 1, Name="Manager" },
new JobTitle {Id= 2, Name="Employee" },
};
var employees = new List<Employee>() {
new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
new Employee{ Id = 3, Name ="Jack", JobTitle = jobTitles[1] },
};
var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.DataSource = employees;
this.Controls.Add(dg);
}
何时:您不想更改 Employee 的JobTitle
如何:通过处理DataGridView
的CellFormatting
事件并将事件 args 的Value
设置为JobTitle
的字符串表示形式
class JobTitle
{
public int Id { get; set; }
public string Name { get; set; }
}
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public JobTitle JobTitle { get; set; }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var jobTitles = new List<JobTitle>() {
new JobTitle {Id= 1, Name="Manager" },
new JobTitle {Id= 2, Name="Employee" },
};
var employees = new List<Employee>() {
new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
new Employee{ Id = 3, Name ="Jack", JobTitle = jobTitles[1] },
};
var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.DataSource = employees;
dg.CellFormatting += (obj, args) =>
{
if (args.RowIndex >= 0 &&
dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
args.Value = ((Employee)dg.Rows[args.RowIndex].DataBoundItem).JobTitle.Name;
};
this.Controls.Add(dg);
}
何时:您希望能够更改Employee
的JobTitle
并且您的 model 中有外键列。
方法:对该属性使用DataGridViewComboBoxColumn
,拥有一个包含所有职位的数据源,并将DisplayMember
和ValueMember
设置为适当的属性。
class JobTitle
{
public int Id { get; set; }
public string Name { get; set; }
}
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int JobTitleId { get; set; }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var jobTitles = new List<JobTitle>() {
new JobTitle {Id= 1, Name="Manager" },
new JobTitle {Id= 2, Name="Employee" },
};
var employees = new List<Employee>() {
new Employee{ Id = 1, Name ="John", JobTitleId = 1 },
new Employee{ Id = 2, Name ="Jane", JobTitleId = 2 },
new Employee{ Id = 2, Name ="Jack", JobTitleId = 2 },
};
var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.DataSource = employees;
dg.Columns.Add(new DataGridViewTextBoxColumn()
{
DataPropertyName = "Id", HeaderText = "Id"
});
dg.Columns.Add(new DataGridViewTextBoxColumn()
{
DataPropertyName = "Name", HeaderText = "Name"
});
dg.Columns.Add(new DataGridViewComboBoxColumn()
{
DataPropertyName = "JobTitleId",
HeaderText = "JobTitleId",
DataSource = jobTitles,
ValueMember = "Id",
DisplayMember = "Name",
});
this.Controls.Add(dg);
}
何时:您希望能够更改Employee
的JobTitle
并且您的 model 中没有外键列,而是希望在 Z20F35E630DAF44DBFA4C3F68F5399D8C8 中使用导航 object。
方法:对该属性使用DataGridViewComboBoxColumn
,具有包含所有职位的数据源,无需将DisplayMember
和ValueMember
设置为适当的属性。 然后处理CellFormatting
设置单元格的显示值,处理CellParsing
从ComboBox
获取值并放入单元格。
class JobTitle
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public JobTitle JobTitle { get; set; }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var jobTitles = new List<JobTitle>() {
new JobTitle {Id= 1, Name="Manager" },
new JobTitle {Id= 1, Name="Employee" },
};
var employees = new List<Employee>() {
new Employee{ Id = 1, Name ="John", JobTitle = jobTitles[0] },
new Employee{ Id = 2, Name ="Jane", JobTitle = jobTitles[1] },
new Employee{ Id = 2, Name ="Jack", JobTitle = jobTitles[1] },
};
var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.DataSource = employees;
dg.Columns.Add(new DataGridViewTextBoxColumn()
{
DataPropertyName = "Id", HeaderText = "Id"
});
dg.Columns.Add(new DataGridViewTextBoxColumn()
{
DataPropertyName = "Name", HeaderText = "Name"
});
dg.Columns.Add(new DataGridViewComboBoxColumn()
{
DataPropertyName = "JobTitle",
HeaderText = "JobTitle",
DataSource = jobTitles,
});
dg.CellFormatting += (obj, args) =>
{
if (args.RowIndex >= 0 &&
dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
{
args.Value =
((Employee)dg.Rows[args.RowIndex].DataBoundItem).JobTitle.ToString();
}
};
dg.CellParsing += (obj, args) =>
{
if (args.RowIndex >= 0 &&
dg.Columns[args.ColumnIndex].DataPropertyName == "JobTitle")
{
args.Value = ((ComboBox)dg.EditingControl).SelectedItem;
args.ParsingApplied = true;
}
};
this.Controls.Add(dg);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.