我有一个绑定到列表的DGV。
Work是一个包含许多属性的类,其中包括一个int类型的status属性。我希望在映射到适当的显示值的DataGridViewComboBoxCell中具有该Status值。
所以映射看起来像
1 = Completed
2 = In Progress
3 = Errored
4 = On Hold
我尝试将DataGridViewComboBoxCell绑定到一个包含状态的int和字符串值的列表。
我一直无法弄清楚如何使work.status在DataGridViewComboBoxCell中显示Statuses.DisplayName。
public class Work
{
public int id {get; set;}
public string name {get; set;}
public int status {get; set;}
public datetime created {get; set;}
public datetime modified {get; set;}
}
public class Statuses
{
public int id {get; set;}
public string DisplayValue {get; set;}
}
如果可以做到,请告诉我。.
答案 0 :(得分:0)
注释中建议的一种可能的解决方案是按照描述的方式“创建” DataGridViewComboBoxColumn
,然后将其添加到网格中。在设置网格数据源之前,请执行此操作。使用组合列Work
将此组合框列映射到DataPropertyName
列表的“ WorkStatus”属性。将列DataPropertyName
设置为“ WorkStatus”应该可以解决问题。
您可能会遇到的一个重要问题是,在设置组合框列之后,将“ 1-完成”,“ 2-正在进行…”等设置为“ int
”值是“状态”中的值。 Work
个项目的列表字段中……太好了!可能总是这样,但是,如果Status
字段之一的值不是1、2、3或4…,则当此值映射到DataError
时,网格将抛出DataError
组合框列。在大多数情况下,直到读取数据和动臂崩溃,您才知道这一点。
重点是,如果您要设置组合框列,然后将数据源中的列“映射”到该列……则最好确保它没有任何无效的“状态”值。否则,将确保发生崩溃(数据错误)。无论如何,最好将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; }
}
项目的“状态”值。如果在数据中找到一个大于4或小于1的值,该怎么办呢?您不能像上面解释的那样随心所欲。该解决方案是简单地使用“未知”字符串值将值“添加”到组合框。这样至少可以“保证”您可以避免无效值引起的数据错误。
将它们放在一起可能会是这样……
下面是发布的Work类,但是我确实更改了一些变量名。这是绑定到网格的类。
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
将需要遍历Status
对象的列表,并“检查”每个状态值,以确保值介于1和4之间(包括1和4)。返回此列表的方法可能会派上用场,如下所示……首先创建“默认” Work
值并将其添加到列表(1、2、3、4),然后循环遍历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
的方法可能类似于以下内容……。首先,我们从上述方法中获取状态列表,然后设置columns属性,并确保将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);
}
下面是使用上述方法的示例。
{{1}}
我希望这会有所帮助。