如何将List <string>绑定到DataGridView控件?


84

我有一个简单的方法List<string>,希望将其显示在DataGridView列中。
如果列表包含更复杂的对象,则只需将列表建立为其DataSource属性的值即可。

但是这样做时:

myDataGridView.DataSource = myStringList;

我看到一列,Length然后显示字符串的长度。

如何在列中显示列表中的实际字符串值?

Answers:


70

那是因为DataGridView寻找包含对象的属性。对于字符串,只有一个属性-长度。因此,您需要一个包装这样的字符串

public class StringValue
{
    public StringValue(string s)
    {
        _value = s;
    }
    public string Value { get { return _value; } set { _value = value; } }
    string _value;
}

然后将List<StringValue>对象绑定到网格。有用


3
DataPropertyName列必须是Value
雷米

分组呢?现在“ A”不等于“ A”,我有两个组“ A”。
罗孚

97

试试这个:

IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();

我希望这有帮助。


13
如果您使用列表而不是IList,则可以使用List.ConvertAll(x => new { Value = x});
Scotty.NET 2012年

7
这可以工作,但是对list_string的更改将不会更新DataGridView。
Pedro77

要更新网格,需要再次运行linq语句。
杰夫

1
dgvSelectedNode.Show()是什么?
段沃克

18

只要您绑定到实现IEnumerable <string>的任何内容,以下内容就应该起作用。它将直接将列绑定到字符串本身,而不是该字符串对象的“属性路径”。

<sdk:DataGridTextColumn Binding="{Binding}" />

我已经测试了这种建议,并且效果很好。它比其他解决方案干净。
古斯塔沃·卡多佐

7
这不是针对Silverlight吗?
NoviceProgrammer 2011年

2
这在WPF中也有效。.为什么您会提出不正确的评论?
Boppity Bop 2013年

4
拒绝投票是因为原始问题具有“ datagridview”标签,这是winforms控件。此解决方案不适用于winfroms。
VIS

13

你也可以使用LINQ和匿名类型描述用少得多的代码实现同样的结果在这里

更新:博客已关闭,这里是内容:

(..)表中显示的值表示字符串的长度,而不是字符串值(!)可能看起来很奇怪,但这是绑定机制在默认情况下的工作方式-给定一个对象,它将尝试绑定到该对象的第一个属性对象(它可以找到的第一个属性)。当传递实例String类时,它绑定到的属性是String.Length,因为没有其他属性可以提供实际的字符串本身。

这意味着要获得正确的绑定,我们需要一个包装器对象,该对象将字符串的实际值作为属性公开:

public class StringWrapper
    {
     string stringValue;
     public string StringValue { get { return stringValue; } set { stringValue = value; } }

     public StringWrapper(string s)
     {
     StringValue = s;
     }
  }   

   List<StringWrapper> testData = new List<StringWrapper>();

   // add data to the list / convert list of strings to list of string wrappers

  Table1.SetDataBinding(testdata);

尽管此解决方案可以按预期工作,但它需要很多行代码(主要是将字符串列表转换为字符串包装器列表)。

我们可以通过使用LINQ和匿名类型来改进此解决方案-我们将使用LINQ查询来创建字符串包装器的新列表(在我们的例子中,字符串包装器将是匿名类型)。

 var values = from data in testData select new { Value = data };

 Table1.SetDataBinding(values.ToList());

我们要做的最后更改是将LINQ代码移至扩展方法:

public static class StringExtensions
  {
     public static IEnumerable CreateStringWrapperForBinding(this IEnumerable<string> strings)
     {
     var values = from data in strings
     select new { Value = data };

     return values.ToList();
     }

这样,我们可以通过对任何字符串集合调用单个方法来重用代码:

Table1.SetDataBinding(testData.CreateStringWrapperForBinding());

8

这是常见问题,另一种方法是使用DataTable对象

DataTable dt = new DataTable();
dt.Columns.Add("column name");

dt.Rows.Add(new object[] { "Item 1" });
dt.Rows.Add(new object[] { "Item 2" });
dt.Rows.Add(new object[] { "Item 3" });

此处详细描述了此问题:http : //www.psworld.pl/Programming/BindingListOfString


2
但是数据表比List <T>重,大多数开发人员会避免使用数据表。
Musikero31 2014年

2

通过LINQ分配非常大的列表时,您可能会遇到性能问题。以下解决方案适用于大型列表,并且无需子类化String:

将DataGridView(此处为“ View”)设置为虚拟模式,创建所需的列并覆盖/注册事件CellValueNeeded

private void View_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
    // Optionally: check for column index if you got more columns
    e.Value = View.Rows[e.RowIndex].DataBoundItem.ToString();
}

那么您只需将列表分配给DataGridView:

List<String> MyList = ...
View.DataSource = MyList;

2

试试这个 :

//i have a 
List<string> g_list = new List<string>();

//i put manually the values... (for this example)
g_list.Add("aaa");
g_list.Add("bbb");
g_list.Add("ccc");

//for each string add a row in dataGridView and put the l_str value...
foreach (string l_str in g_list)
{
    dataGridView1.Rows.Add(l_str);
}

1
您意识到这个问题大约6岁,已经回答了吗?
Hozikimaru 2015年

2
您必须先将列添加到datagrid视图,否则将不起作用
deltanine

0

一种替代方法是使用新的帮助器函数,该函数将从List中获取值并在DataGridView中进行更新,如下所示:

    private void DisplayStringListInDataGrid(List<string> passedList, ref DataGridView gridToUpdate, string newColumnHeader)
    {
        DataTable gridData = new DataTable();
        gridData.Columns.Add(newColumnHeader);

        foreach (string listItem in passedList)
        {
            gridData.Rows.Add(listItem);
        }

        BindingSource gridDataBinder = new BindingSource();
        gridDataBinder.DataSource = gridData;
        dgDataBeingProcessed.DataSource = gridDataBinder;
    }

然后我们可以通过以下方式调用此函数:

    DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.