我有一个简单的List<string>
,我希望它显示在DataGridView
列中。
如果列表包含更复杂的对象,则只需将列表建立为其DataSource
属性的值。
但这样做的时候:
myDataGridView.DataSource = myStringList;
我得到一个名为Length
的列,并显示字符串的长度。
如何从列中的列表中显示实际的字符串值?
答案 0 :(得分:89)
试试这个:
IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();
我希望这会有所帮助。
答案 1 :(得分:67)
这是因为DataGridView查找包含对象的属性。对于字符串,只有一个属性 - 长度。所以,你需要一个像这样的字符串的包装器
public class StringValue
{
public StringValue(string s)
{
_value = s;
}
public string Value { get { return _value; } set { _value = value; } }
string _value;
}
然后将List<StringValue>
对象绑定到您的网格。它的工作原理
答案 2 :(得分:19)
只要您绑定到实现IEnumerable&lt; string&gt;的任何内容,以下内容就可以正常工作。它会将列直接绑定到字符串本身,而不是绑定到该字符串对象的属性路径。
<sdk:DataGridTextColumn Binding="{Binding}" />
答案 3 :(得分:13)
您还可以使用linq和匿名类型以更少的代码实现相同的结果,如here所述。
更新:博客已关闭,这是内容:
(..)表中显示的值表示字符串的长度而不是字符串值(!) 这可能看起来很奇怪,但这是绑定机制默认工作的方式 - 给定一个对象它将尝试绑定到该对象的第一个属性(它可以找到的第一个属性)。 当传递一个实例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();
}
这样我们可以通过在任何字符串集合上调用single方法来重用代码:
Table1.SetDataBinding(testData.CreateStringWrapperForBinding());
答案 4 :(得分: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
答案 5 :(得分:2)
通过LINQ分配非常大的列表时,可能会遇到性能问题。 以下解决方案适用于大型列表,没有子类化String:
将DataGridView(此处&#34; View&#34;)设置为虚拟模式,创建所需的列并覆盖/注册事件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;
答案 6 :(得分: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);
}
答案 7 :(得分: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>);