シンプルList<string>
なものがあり、DataGridView
列に表示したいのですが。
リストにさらに複雑なオブジェクトが含まれる場合は、単にリストをそのDataSource
プロパティの値として確立します。
しかし、これを行うとき:
myDataGridView.DataSource = myStringList;
という列Length
が表示され、文字列の長さが表示されます。
リストの実際の文字列値を列に表示するにはどうすればよいですか?
回答:
これは、DataGridViewが含まれているオブジェクトのプロパティを検索するためです。文字列の場合、プロパティは1つだけです-長さ。したがって、このような文字列のラッパーが必要です
public class StringValue
{
public StringValue(string s)
{
_value = s;
}
public string Value { get { return _value; } set { _value = value; } }
string _value;
}
次に、List<StringValue>
オブジェクトをグリッドにバインドします。できます
これを試して:
IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();
これがお役に立てば幸いです。
List.ConvertAll(x => new { Value = x});
。
IEnumerable <string>を実装するものにバインドされている限り、以下は機能するはずです。文字列オブジェクトのプロパティパスではなく、文字列自体に列を直接バインドします。
<sdk:DataGridTextColumn Binding="{Binding}" />
linq型とanonymous型を使用して、ここで説明するようにはるかに少ないコードで同じ結果を達成することもできます。
更新:ブログがダウンしています。内容は次のとおりです。
(..)表に示されている値は、文字列値ではなく文字列の長さを表しています(!)奇妙に思えるかもしれませんが、デフォルトでは、このようにバインドメカニズムが機能します。オブジェクトを指定すると、その最初のプロパティにバインドしようとします。オブジェクト(見つけることができる最初のプロパティ)。インスタンスに渡されると、実際の文字列自体を提供するプロパティは他にないため、バインドするプロパティの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());
これは一般的な問題です。別の方法は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を参照してください。
LINQを介して非常に大きなリストを割り当てると、パフォーマンスの問題が発生する可能性があります。次のソリューションは、文字列をサブクラス化せずに大きなリストに適しています。
DataGridView(ここでは「ビュー」)を仮想モードに設定し、必要な列を作成して、イベント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;
これを試して :
//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);
}
別の方法は、リストから値を取得し、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>);
DataPropertyName
列でなければならないのValue