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

agn*_*zka 78 c# binding datagridview

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

但是当这样做时:

myDataGridView.DataSource = myStringList;
Run Code Online (Sandbox Code Playgroud)

我得到一个名为的列,Length并显示字符串的长度.

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

小智 92

试试这个:

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

我希望这有帮助.

  • 如果您使用List而不是IList,则可以使用`List.ConvertAll(x => new {Value = x});`. (11认同)
  • 这有效,但对list_string的更改不会更新DataGridView. (7认同)
  • 什么是 dgvSelectedNode.Show() ? (2认同)

sin*_*inm 67

这是因为DataGridView查找包含对象的属性.对于字符串,只有一个属性 - 长度.所以,你需要一个像这样的字符串的包装器

public class StringValue
{
    public StringValue(string s)
    {
        _value = s;
    }
    public string Value { get { return _value; } set { _value = value; } }
    string _value;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 列的`DataPropertyName`必须是'Value` (3认同)

jam*_*ode 19

只要您绑定到实现IEnumerable <string>的任何内容,以下内容就可以正常工作.它会将列直接绑定到字符串本身,而不是绑定到该字符串对象的属性路径.

<sdk:DataGridTextColumn Binding="{Binding}" />
Run Code Online (Sandbox Code Playgroud)

  • 不是这个特定于silverlight? (7认同)
  • Downvoting因为原始问题有"datagridview"标签,这是winforms控件.此解决方案不适用于winfroms. (3认同)
  • 这也适用于WPF ..为什么你会提出不正确的评论呢? (2认同)

Jar*_*das 13

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

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

(..)表中显示的值表示字符串的长度而不是字符串值(!)它可能看起来很奇怪,但这是默认情况下绑定机制的工作方式 - 给定一个对象它将尝试绑定到该字符串的第一个属性object(它可以找到的第一个属性).当传递一个实例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);
Run Code Online (Sandbox Code Playgroud)

虽然此解决方案按预期工作,但它需要相当多的代码行(主要是将字符串列表转换为字符串包装器列表).

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

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

 Table1.SetDataBinding(values.ToList());
Run Code Online (Sandbox Code Playgroud)

我们要做的最后一个更改是将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();
     }
Run Code Online (Sandbox Code Playgroud)

这样我们就可以通过在任何字符串集合上调用single方法来重用代码:

Table1.SetDataBinding(testData.CreateStringWrapperForBinding());
Run Code Online (Sandbox Code Playgroud)


小智 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" });
Run Code Online (Sandbox Code Playgroud)

这里详细描述了这个问题:http://www.psworld.pl/Programming/BindingListOfString

  • 但是数据表比List &lt;T&gt;重,大多数开发人员会避免使用数据表。 (2认同)