我有一个具有多个属性的自定义对象,其中一个返回一个列表。这是对象的代码:
public class SearchResult
{
private int eventId;
private String eventTitle;
private int startDate;
private List<String> tags;
// Properties
public int EventId { get { return this.eventId; } }
public String EventTitle { get { return this.eventTitle; } }
public int StartDate { get { return this.startDate; } }
public List<String> Tags { get { return this.tags; } }
public SearchResult(int eventId, String eventTitle, int startDate, List<String> tags)
{
// Constructor code
}
public List<String> GetTags()
{
return this.tags;
}
}
我还有一个DataGridViewComboBoxColumn
我想绑定到Tags
属性的东西。基本上,每个SearchResult
对象都将显示在自己的行中,我希望每个对象的List<String>
inTags
属性都显示在ComboBox
该行的单元格中。这是我到目前为止的代码DataGridView
:
BindingList<SearchResult> results = new BindingList<SearchResult>();
results.Add(new SearchResult(1, "This is a title", 2012, new List<String> { "Tag1", "Tag with a long name1" }));
results.Add(new SearchResult(2, "The quick brown fox", 2012, new List<String> { "Stack", "Overflow" }));
results.Add(new SearchResult(3, "In this tutorial, you create a class that is the type for each object in the object collection. ", 2012, new List<String> { "NYSE", "FTSE" }));
results.Add(new SearchResult(4, "another long piece of title text", -999, new List<String> { "Rabbits", "Chickens" }));
MyDataGrid.AutoGenerateColumns = false;
MyDataGrid.AllowUserToAddRows = false;
MyDataGrid.AllowUserToDeleteRows = false;
MyDataGrid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
MyDataGrid.BackgroundColor = System.Drawing.SystemColors.Control;
MyDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
MyDataGrid.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
MyDataGrid.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.DisplayedCells;
MyDataGrid.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
DataGridViewTextBoxColumn eventIdColumn = new DataGridViewTextBoxColumn();
eventIdColumn.DataPropertyName = "EventId";
eventIdColumn.HeaderText = "Event ID";
eventIdColumn.ReadOnly = true;
eventIdColumn.Width = 84;
DataGridViewTextBoxColumn eventTitleColumn = new DataGridViewTextBoxColumn();
eventTitleColumn.DataPropertyName = "EventTitle";
eventTitleColumn.HeaderText = "Event Title";
eventTitleColumn.ReadOnly = true;
eventTitleColumn.Width = 368;
DataGridViewTextBoxColumn startDateColumn = new DataGridViewTextBoxColumn();
startDateColumn.DataPropertyName = "StartDate";
startDateColumn.HeaderText = "Start Date";
startDateColumn.ReadOnly = true;
startDateColumn.Width = 130;
//I think I need to insert the code for the tags column here, but I'm not sure
MyDataGrid.Columns.Add(eventIdColumn);
MyDataGrid.Columns.Add(eventTitleColumn);
MyDataGrid.Columns.Add(startDateColumn);
//MyDataGrid.Columns.Add(tagsColumn);
MyDataGrid.DataSource = results;
我从网上找到的教程中得出了这段代码,它运行良好。
我一直在尝试将 的Tags
属性绑定SearchResult
到 a DataGridViewComboBoxColumn
,但我不确定如何。我一直在看这个问题,它提供了这个代码:
column.DataPropertyName = "Foo";
column.DisplayMember = "SomeNameField";
column.ValueMember = "Bar"; // must do this, empty string causes it to be
// of type string, basically the display value
// probably a bug in .NET
column.DataSource = from foo in Foo select foo;
grid.DataSource = data;
我遇到麻烦的原因是我不理解的链接问题的一些细微差别。
- 根据文档和链接的问题,
DisplayMember
应该链接到“包含实例描述”的属性,但是由于SearchResult
对象是动态添加的并且没有与之关联的任何描述,我应该将其留空吗? ValueMember
给了我类似的问题,因为即使在阅读了它的文档之后我也不确定该放什么。- 在链接的问题中,接受的答案使用 LINQ 一次绑定整个数据网格。我应该这样做吗?我不确定如何根据我的情况修改该代码,但我认为它会是这样的。
:
tagsColumn.DataPropertyName = "Tags";
tagsColumn.DisplayMember = ""; // I'm unsure of what to put here
tagsColumn.ValueMember = ""; // Once again, I don't know what to set this to
我还认为我应该有一个设置DataSource
列的行,例如
tagsColumn.DataSource = <some LINQ query, perhaps?>
但我不知道,因为我能找到的唯一最相关的 C# 源代码就是那个问题。
更新:
我确实找到了第二个问题,该问题建议使用与此类似的代码进行数据绑定:
// reference the combobox column
DataGridViewComboBoxColumn cboBoxColumn = (DataGridViewComboBoxColumn)dataGridView1.Columns[0];
cboBoxColumn.DataSource = Choice.GetChoices();
cboBoxColumn.DisplayMember = "Name"; // the Name property in Choice class
cboBoxColumn.ValueMember = "Value"; // ditto for the Value property
基于此,我 a) 添加了该GetTags()
方法SearchResult
并将此代码添加到我的DataGridView
初始化代码中:
DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
tagsColumn.DataSource = SearchResult.GetTags(); // ERROR
tagsColumn.DisplayMember = ""; // Still not sure
tagsColumn.ValueMember = ""; // ??
但是,当我尝试运行它时,Visual Studio 在第二行给我一个错误:
An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()'
更新 2:
我仍在寻找这个没有成功。我不明白如何使用其他属性(例如EventId
)我可以简单地将数据属性名称声明为EventId
,它将显示在表中,但我不能对ComboBox
列执行此操作。
Tags
由于对象是在一个单独的类中实例化并放入一个列表中,因此我应该遍历整个对象数组(其中可能有数百个)来绑定属性对我来说似乎没有意义到ComboBox
每个实例的列,当我不需要遍历SearchResult
对象列表来绑定其他属性时,例如EventId
.
为什么这个 binding-properties-by-name 只适用于某些属性而不适用于其他属性?