我通过在表单的构造函数中设置 DataSource 属性将 DataGridView 绑定到
BindingList<Thing>
。
InitializeComponent();
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = thingsList;
事物定义为:
public class Thing
{
public Prop1 { get; set; }
public Prop2 { get; set; }
}
我希望能够从 DataGridView 编辑器的“数据绑定列”列表中选择 Thing 类的属性。
“添加列”对话框需要什么才能显示我要绑定的类型的属性?
你是对的,可以使用可视化设计器来分配数据绑定到列的属性的名称。
但是,这有一个缺点,即属性的名称将是一个字符串。如果稍后您决定更改属性的名称,则编译器无法检查您是否也忘记更改数据绑定项。
最好在表单的构造函数中使用
nameof(...)
来分配它。使用Visual Studio设计器添加DataGridViewColumn,并指定一个值的显示格式,但是该列中应该显示什么属性可以在构造函数中完成。
public MyForm()
{
InitializeComponent(); // creates the columns
// define which column should show the value of which property:
this.columnProp1 = nameof(Thing.Prop1);
this.columnProp2 = nameof(Thing.Prop2);
}
现在,如果稍后您决定为类和属性提供正确的标识符,例如类
Product
、属性 Name
和 Price
,如果您忘记更新构造函数,编译器会抱怨。
表单类中的其他有用更改:
BindingList<Thing> DisplayedThings
{
get => (BindingList<Thing>) this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
}
要让
Thing
显示在当前选定的行中:
Thing CurrentThing => (Thing)(this.dataGridView1.CurrentRow.DataBoundItem);
如果操作员可以选择多行:
IEnumerable<Thing> SelectedThings => this.dataGridView1.SelectedRows
.Cast<DataGridViewRow>()
.Select(row => row.DataBoundItem)
.Cast<Thing>();
用途:
IEnumerable<Thing> GetThingsToDisplay() { TODO: implement }
首次显示表单时,填写 DataGridView:
void OnForm_Load(object sender, ...)
{
this.DisplayedThings = new BindingList<Thing>(this.GetThingsToDisplay().ToList());
}
如果操作员可以编辑显示的内容:添加行、删除行、编辑单元格,完成后他可以按“立即应用”:
OnButtonApplyNow_Clicked(object sender, ...)
{
ICollection<Thing> editedThings = this.DisplayedThings;
ICollection<Thing> originalThings = this.GetOriginalDisplayedThings() // TODO: implement
// use LINQ to find out which rows are added / removed / changed
}