如何将 DisplayMember 和 ValueMember 添加到具有指定数据源的单个 ComboBox 项?
How can I add a DisplayMember and ValueMember to a single ComboBox Item that has an assigned DataSource?
我成功地将 Display/Value 对添加到组合框,如下所示:
List<Student> BRStudents =
studentsList.Where(h => h.EnrolledInAYttFM)
.Where(i =>
i.RecommendedNextTalkTypeID.Equals(BIBLE_READING_TALK_TYPE))
.OrderBy(j => j.WeekOfLastAssignment)
.ToList();
comboBoxBR.DataSource = BRStudents;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
...但我随后(在某些情况下)想向 comboBoxBR 添加另一个项目,该项目不存在于 BRStudents 列表中。如果我尝试这样做:
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
string fullName = AYttFMConstsAndUtils.GetStudentFullNameForID(ah.StudentID_FK);
comboBoxBR.Items.Add(fullName);
...我明白了,"Items collection cannot be modified when the DataSource property is set."
真的,我想做这样的事情:
comboBoxBR.Items.Add(fullName, ah.StudentID_FK);
有没有办法将两个结果(Student 列表和单个 AssignmentHistory)组合成字典或类似的集合,然后将 that 指定为数据源组合框BR?
为了完整披露,以下是 Student 和 AssignmentHistory 的定义:
public class Student
{
public int StudentID { get; set; }
public int FamilyID { get; set; }
public bool EnrolledInAYttFM { get; set; }
public DateTime DateEnrolledOrHiatusAYttFM { get; set; }
public bool GivesBibleReading { get; set; }
public bool PresentsICRVBS { get; set; }
public bool IsHouseholder { get; set; }
public bool IsMale { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddr { get; set; }
public DateTime WeekOfLastAssignment { get; set; }
public int RecommendedNextTalkTypeID { get; set; }
public int NextCounselPoint { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
public class AssignmentHistory
{
public DateTime WeekOfAssignment { get; set; }
public int TalkType { get; set; }
public int StudentID_FK { get; set; }
public int AssistantID_FK { get; set; }
public int CounselPoint { get; set; }
public bool HasBeenEmailed { get; set; }
public bool SlipHasBeenPrinted { get; set; }
}
首先想到的不是将元素添加到组合的 Items 集合(如果设置了数据源,则不可能),而是将元素添加到用作数据源的 List<Students>
本身,但这没有到达您的 objective 因为没有适当的机制来通知 ComboBox DataSource 有一个新元素。除非将列表重新绑定到组合框,否则看不到添加的元素。为此,您首先需要取消绑定以前的数据源,然后重新绑定列表。
// Assuming a lot about your student class, hope it's clear the intention
BRStudents.Add(new Student() { newName = "ANewStudent", ID = 1} );
comboBoxBR.DataSource = null;
comboBoxBR.DataSource = BRStudents;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
但是,有一个更好的解决方案,那就是 class BindingList(T)
此 class 能够刷新您绑定其实例的对象。
所以第一次绑定combo的时候要写
BindingList<Student> bl = new BindingList<Student>(BRStudents);
comboBoxBR.DataSource = bl;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
以及当您想向您编写的列表中添加新元素时
(如果需要,在全局范围内移动 bl)
bl.Add(new Student() { newName = "ANewStudent", ID = 1} );
文档指出您应该调用 ResetBindings 来强制刷新控件,但这似乎并不总是必需的...
我成功地将 Display/Value 对添加到组合框,如下所示:
List<Student> BRStudents =
studentsList.Where(h => h.EnrolledInAYttFM)
.Where(i =>
i.RecommendedNextTalkTypeID.Equals(BIBLE_READING_TALK_TYPE))
.OrderBy(j => j.WeekOfLastAssignment)
.ToList();
comboBoxBR.DataSource = BRStudents;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
...但我随后(在某些情况下)想向 comboBoxBR 添加另一个项目,该项目不存在于 BRStudents 列表中。如果我尝试这样做:
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
string fullName = AYttFMConstsAndUtils.GetStudentFullNameForID(ah.StudentID_FK);
comboBoxBR.Items.Add(fullName);
...我明白了,"Items collection cannot be modified when the DataSource property is set."
真的,我想做这样的事情:
comboBoxBR.Items.Add(fullName, ah.StudentID_FK);
有没有办法将两个结果(Student 列表和单个 AssignmentHistory)组合成字典或类似的集合,然后将 that 指定为数据源组合框BR?
为了完整披露,以下是 Student 和 AssignmentHistory 的定义:
public class Student
{
public int StudentID { get; set; }
public int FamilyID { get; set; }
public bool EnrolledInAYttFM { get; set; }
public DateTime DateEnrolledOrHiatusAYttFM { get; set; }
public bool GivesBibleReading { get; set; }
public bool PresentsICRVBS { get; set; }
public bool IsHouseholder { get; set; }
public bool IsMale { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddr { get; set; }
public DateTime WeekOfLastAssignment { get; set; }
public int RecommendedNextTalkTypeID { get; set; }
public int NextCounselPoint { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
public class AssignmentHistory
{
public DateTime WeekOfAssignment { get; set; }
public int TalkType { get; set; }
public int StudentID_FK { get; set; }
public int AssistantID_FK { get; set; }
public int CounselPoint { get; set; }
public bool HasBeenEmailed { get; set; }
public bool SlipHasBeenPrinted { get; set; }
}
首先想到的不是将元素添加到组合的 Items 集合(如果设置了数据源,则不可能),而是将元素添加到用作数据源的 List<Students>
本身,但这没有到达您的 objective 因为没有适当的机制来通知 ComboBox DataSource 有一个新元素。除非将列表重新绑定到组合框,否则看不到添加的元素。为此,您首先需要取消绑定以前的数据源,然后重新绑定列表。
// Assuming a lot about your student class, hope it's clear the intention
BRStudents.Add(new Student() { newName = "ANewStudent", ID = 1} );
comboBoxBR.DataSource = null;
comboBoxBR.DataSource = BRStudents;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
但是,有一个更好的解决方案,那就是 class BindingList(T)
此 class 能够刷新您绑定其实例的对象。
所以第一次绑定combo的时候要写
BindingList<Student> bl = new BindingList<Student>(BRStudents);
comboBoxBR.DataSource = bl;
comboBoxBR.DisplayMember = "FullName";
comboBoxBR.ValueMember = "StudentID";
以及当您想向您编写的列表中添加新元素时
(如果需要,在全局范围内移动 bl)
bl.Add(new Student() { newName = "ANewStudent", ID = 1} );
文档指出您应该调用 ResetBindings 来强制刷新控件,但这似乎并不总是必需的...