2012-06-29 32 views
2

我有一个自定义对象与几个属性,其中之一返回一个列表。这是该对象的代码:如何将DataGridViewComboBoxColumn绑定到返回列表的对象的属性/方法?

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对象将显示在其自己的行中,并且我希望在每个对象的Tags属性中的List<String>显示在该行的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; 

我得出这个代码a tutorial I found online,和它完美的作品。

我一直在试图将SearchResultTags属性绑定到DataGridViewComboBoxColumn,但我不确定如何。我一直在寻找this question,它提供了这样的代码:

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; 

我在遇到麻烦的原因是因为链接的问题,我不明白的一些细微差别的。

  1. 根据the documentation,以及相关的问题,DisplayMember应该链接到“包含实例的说明”的属性,但由于SearchResult对象动态添加或不具有与它们相关的任何说明,应我只是把它留空?
  2. ValueMember给了我类似的问题,因为即使在阅读its documentation后,我仍然不确定要放什么。
  3. 在链接问题中,接受的答案使用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#源代码,我已经能够找到这个问题。

UPDATE:

我发现a second question这表明数据绑定类似下面的代码:此基础上

// 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 

,我一个)的添加GetTags()方法SearchResult,并将此代码到我的DataGridView初始化代码:

 DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn(); 
     tagsColumn.DataSource = SearchResult.GetTags(); // ERROR 
     tagsColumn.DisplayMember = ""; // Still not sure 
     tagsColumn.ValueMember = ""; // ?? 

但是,Visual Studio的给我上的S错误当我尝试运行此的Econd行:

An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()' 

更新2:

我还在摸索这个没有成功。我不明白如何与其他属性(例如EventId)我可以简单地声明数据属性名称为EventId,它将显示在表中,但我不能这样做与ComboBox列。

由于对象是在一个单独的类中实例化并放入一个列表中,所以我不应该通过整个对象数组(其中可能有几百个)进行循环,将Tags属性绑定到每个实例的ComboBox列,当我不需要遍历SearchResult对象的列表来绑定其他属性,例如EventId

为什么此绑定属性的名称只适用于某些属性而不是其他属性?

+1

错误来自您调用SearchResult.GetTags();您需要将其设为静态方法,或者首先实例化SearchResult(新...) – blearn

+0

@blearn在第二个链接问题的答案中,该对象未实例化。另外,由于'SearchResult'对象会动态地添加到这个列表中,所以在一个单独的类中的方法中,除非我遍历它们,否则我不一定能够访问它们,在这种情况下,我可能只是跳过数据绑定,手动填充'DataGridView',我试图避免这么做。 –

回答

3

我不太明白你为什么要用DataGridViewComboBoxColumn来显示元素列表。此列种类旨在允许用户选择多种可能性之一。它接缝它不是你的情况,因为你没有public string SelectedTag{get;set;}属性来存储它。据我了解您的模型,您已为SearchResult选择了许多标签,并且希望以网格显示它们。

如文档状态: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.datasource

获取或设置该[的DataSource]属性获取或设置由CellTemplate属性返回的对象的数据源属性。设置此属性还会将该列中的每个单元格的数据源属性设置为,并刷新列显示。要覆盖单个单元格的指定值,请在设置列值后设置单元格值。

DataGridViewComboBoxColumn根本没有将项目属性绑定到数据源的功能,因为它假定只有一个元素列表被用作所有数据网格行的数据源。

我还假设您将为此列设置ReadOnly = true属性,就像您对其他所有属性一样。如果是这样,它会阻止用户形式看到标签列表,因为下拉列表永远不会显示。

如果你的魔杖,显示在只读模式字符串列表,我建议扁平化的标签,以单个字符串此列表:

public string Tags { get { return string.Join(", ", tags); } } 

和文本列显示。

+0

我原本想这样做,因为我不确定是否有其他方法,但是最终我使用了与您发布的代码类似的东西(使用'Join')并创建了自己的用户控件。 –

1

对于错误,我可以建议你做一个类的实例,然后调用该方法,因为它不是静态的,或者你可以使你的方法是静态的。

而且当你需要comboboxcolumn,

DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn(); 
     tagsColumn.DataSource = SearchResult.GetTags(); // ERROR 
     tagsColumn.DisplayMember = ""; // Still not sure 
     tagsColumn.ValueMember = ""; // ?? 

主要是我们有类似的对象下拉菜单中国家(ID,姓名),所以DisplayMember =名称将显示在下拉列表的文本,而ValueMember = ID将被使用数据库中的引用表。但这不是你的情况。

在这里你有一个字符串列表显示在下拉列表中,所以你不需要设置它们。 作为书面here

当dataSource属性被设置为一个字符串数组,然后ValueMember 和DisplayMember不需要被设置,因为 阵列中的每个字符串将被用于两个值和显示。

+0

除了使用对象的实例之外,没有其他方法可以做到这一点吗?我不能像其他房产一样自动做到这一点?看到我对原始问题的评论。 –

相关问题