cmets 中建议的一种可能解决方案是按照您描述的方式“创建”DataGridViewComboBoxColumn,然后将其添加到网格中。在设置网格数据源之前执行此操作。将此组合框列映射到Work 列表的“WorkStatus”属性是使用组合列DataPropertyName 完成的。将列 DataPropertyName 设置为“WorkStatus”应该可以解决问题。
您可能会遇到的一个重要问题是,如果在设置组合框列后使用 1 – Complete, 2 – In Progress... 等。int 值 1-4 是“状态”字段中的值Work 项目列表……希望如此!情况可能总是如此,但是如果 Status 字段之一的值不是 1、2、3 或 4……那么当此值映射到组合框列时,网格将抛出 DataError .在大多数情况下,直到数据被读取并且繁荣崩溃时,您才会知道这一点。
关键是,如果您要设置一个组合框列,然后将一个列从数据源“映射”到该列……您最好确保它没有任何无效的“状态”值。否则会导致崩溃(数据错误)。无论如何,最好连接DataError。
鉴于此,似乎有必要至少“检查”以确保当数据绑定到网格时不会发生类似的事情。一个简单的解决方案是遍历所有数据(在将其绑定到网格之前)并“检查每个Work 项目的“状态”值。未知的是,如果在数据中发现大于 4 或小于 1 的值该怎么办。你不能像上面解释的那样放手。此解决方案是简单地将值“添加”到具有“未知”字符串值的组合框中。这将至少“保证”您将避免无效值导致的数据错误。
把这些放在一起可能会变成这样……
下面是发布的 Work 类,但我确实更改了一些变量名称。这是绑定到网格的类。
public class Work {
public int WorkID { get; set; }
public string WorkName { get; set; }
public int WorkStatus { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
}
接下来是用于定义Status 对象的Status 类。这用于组合框列。添加了一个构造函数以及重写的Equals 方法。这将有助于使用列表的 Contains 属性“检查”以查看现有的“状态”值是否已经在列表中。
public class Status : IEquatable<Status> {
public int StatusID { get; set; }
public string StatusString { get; set; }
public Status(int statusID, string statusString) {
StatusID = statusID;
StatusString = statusString;
}
public override bool Equals(object obj) {
if (obj.GetType() != GetType()) return false;
return Equals(obj as Status);
}
public bool Equals(Status that) {
return that != null && this.StatusID == that.StatusID;
}
public override int GetHashCode() {
var hashCode = -1280899892;
hashCode = hashCode * -1521134295 + StatusID.GetHashCode();
return hashCode;
}
}
设置ListOfStatus 将需要遍历Work 对象列表并“检查”每个状态值,确保值介于1 和4 之间。返回此列表的方法可能会派上用场,可能如下所示……首先创建“默认”Status 值并将其添加到列表中(1、2、3、4),然后循环通过 @ 987654340@ 项添加任何尚未在状态列表中的值。
private List<Status> GetStatusList(List<Work> workItems) {
List<Status> listOfStatus = new List<Status>();
// add the default values for the combo boxes
Status curStatus = new Status(1, "Complete");
listOfStatus.Add(curStatus);
curStatus = new Status(2, "In Progress");
listOfStatus.Add(curStatus);
curStatus = new Status(3, "Errored");
listOfStatus.Add(curStatus);
curStatus = new Status(4, "On Hold");
listOfStatus.Add(curStatus);
// check to make sure the data (workItems) does NOT have any values in the Status field...
// that are NOT one of the values above... (specifically 1, 2, 3 or 4)
// if the value is NOT one of the values above... we will simply add it to the list
Status unknownStatus;
foreach (Work work in workItems) {
if (work.WorkStatus < 1 || work.WorkStatus > 4) {
unknownStatus = new Status(work.WorkStatus, "Unknown_" + work.WorkStatus);
if (!listOfStatus.Contains(unknownStatus)) {
listOfStatus.Add(unknownStatus);
}
}
}
return listOfStatus;
}
现在我们有一个很好的Status 对象列表,我们可以继续创建组合框列并将此列表用作组合列的数据源。给定Work 对象的列表是我们创建此列所需的全部内容,返回此DataGridViewComboBoxColumn 的方法可能如下所示……。首先,我们从上述方法中获取状态列表,然后设置列属性,确保设置列DataPropertyName 以匹配Work 对象WorkStatus 属性。如果这不匹配,则该列将无法正确映射。添加的“状态”列最终将作为网格中的第一列,因此您可能需要更改其序数值。
private DataGridViewComboBoxColumn GetComboColumn(List<Work> listOfWork) {
List<Status> ListOfStatus = GetStatusList(listOfWork);
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.Name = "Status";
comboCol.DataPropertyName = "WorkStatus";
comboCol.DisplayMember = "StatusString";
comboCol.ValueMember = "StatusID";
comboCol.DataSource = ListOfStatus;
return comboCol;
}
使用上述方法的示例如下。
private void Form1_Load(object sender, EventArgs e) {
List<Work> ListOfWork = new List<Work>();
FillListOfWork(ListOfWork);
dataGridView1.Columns.Add(GetComboColumn(ListOfWork));
dataGridView1.DataSource = ListOfWork;
}
private void FillListOfWork(List<Work> ListOfWork) {
Work newWork;
Random rand = new Random();
for (int i = 0; i < 100; i++) {
newWork = new Work();
newWork.WorkID = i;
newWork.WorkName = "Work Name " + i;
newWork.WorkStatus = rand.Next(1, 5);
newWork.DateCreated = DateTime.Now;
newWork.DateModified = DateTime.Now;
ListOfWork.Add(newWork);
}
}
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) {
MessageBox.Show("DataError: " + e.Exception.Message);
}
我希望这会有所帮助。