C# 如何将DataGridViewComboBoxColumn绑定到返回列表的对象的属性/方法?

C# 如何将DataGridViewComboBoxColumn绑定到返回列表的对象的属性/方法?,c#,winforms,data-binding,datagridview,C#,Winforms,Data Binding,Datagridview,我有一个具有多个属性的自定义对象,其中一个属性返回一个列表。这是对象的代码: public class SearchResult { private int eventId; private String eventTitle; private int startDate; private List<String> tags; // Properties public int EventId { get { return this.e

我有一个具有多个属性的自定义对象,其中一个属性返回一个列表。这是对象的代码:

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;
    }
}
我从中派生了这段代码,它工作得非常完美

我一直在尝试将
SearchResult
标记
属性绑定到
datagridviewcomboxcolumn
,但我不确定如何绑定。我一直在看,它提供了以下代码:

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立即绑定整个datagrid。我应该这样做吗?我不确定如何根据我的情况修改代码,但我认为应该是这样的
  • :

    我还假设我应该有一行设置列的
    数据源
    ,例如

    tagsColumn.DataSource = <some LINQ query, perhaps?>
    
    基于此,我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
    列来执行此操作

    由于对象是在一个单独的类中实例化并放在一个列表中的,因此对于我来说,必须循环遍历整个对象数组(其中可能有几百个)以将每个实例的
    标记
    属性绑定到
    组合框
    列似乎没有意义,当我不需要在
    SearchResult
    对象列表中循环以绑定其他属性时,例如
    EventId


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

    对于错误,我建议您创建一个类实例,然后调用该方法,因为它不是静态的,或者您可以将方法设置为静态的

    此外,由于您需要comboboxcolumn

    DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
            tagsColumn.DataSource = SearchResult.GetTags(); // ERROR 
            tagsColumn.DisplayMember = ""; // Still not sure
            tagsColumn.ValueMember = ""; // ??
    
    大多数情况下,我们都有国家(id,名称)等对象的下拉列表,因此DisplayMember=name将在下拉列表中显示为文本,而ValueMember=id将在数据库中的引用表中使用。但这不是您的情况

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

    如果DataSource属性设置为字符串数组,则ValueMember 不需要设置和DisplayMember,因为 数组将用于值和显示


    我不太明白为什么要使用
    datagridviewcomboxcolumn
    来显示元素列表。这种列类型的设计允许用户从多种可能性中选择一种。这不是您的情况,因为您没有选择的
    公共字符串tag{get;set;}
    属性来存储它。据我所知,您已经为您的
    搜索结果选择了许多标记,您希望在网格中显示它们

    如文件所述:

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

    DataGridViewComboxColumn根本无法将items属性绑定到数据源,因为它假定只有一个元素列表用作数据网格所有行的数据源

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

    如果您希望以只读模式显示字符串列表,我建议将此标记列表展平为单个字符串:

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

    并将其显示在文本列中。

    调用SearchResult.GetTags()时出错;您需要将其设置为静态方法,或者首先实例化SearchResult(new…@blearn)。在对第二个链接问题的回答中,对象没有实例化。另外,由于
    SearchResult
    对象将动态添加到此列表中,在单独类中的方法中,我不必访问它们,除非我迭代它们,在这种情况下,我最好跳过数据绑定并手动填充
    DataGridView
    ,我正试图避免这样做。除了使用对象的实例之外,没有其他方法可以做到这一点吗?我不能像处理其他属性一样自动完成它?请参阅我对原始问题的评论。我最初想这样做是因为我不确定其他方法,但我最终使用了与您发布的代码类似的东西(使用
    加入
    )并创建了我自己的用户控件。很抱歉,评论太晚了,但如果您仍在,请,我有一个类似于OP的对象列表,它有一个“SelectedTag”和“AvailableTag”属性,并且希望给每一行自己的“AvailableTag”列表提供不同的选项。是否有任何方法可以使用设计器/而不手动绑定所有内容?
    
    An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()'
    
    DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
            tagsColumn.DataSource = SearchResult.GetTags(); // ERROR 
            tagsColumn.DisplayMember = ""; // Still not sure
            tagsColumn.ValueMember = ""; // ??
    
    public string Tags { get { return string.Join(", ", tags); } }