いくつかのプロパティを持つカスタム オブジェクトがあり、そのうちの 1 つがリストを返します。オブジェクトのコードは次のとおりです。
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;
}
}
DataGridViewComboBoxColumn
プロパティにバインドしたいもありTags
ます。基本的に、各SearchResult
オブジェクトは独自の行に表示され、各オブジェクトのList<String>
in theTags
プロパティがComboBox
その行のセルに表示されるようにします。これは私がこれまでに持っているコードですDataGridView
:
BindingList<SearchResult> results = new BindingList<SearchResult>();
results.Add(new SearchResult(1, "This is a title", 2012, new List<String> { "Tag1", "Tag with a long name1" }));
results.Add(new SearchResult(2, "The quick brown fox", 2012, new List<String> { "Stack", "Overflow" }));
results.Add(new SearchResult(3, "In this tutorial, you create a class that is the type for each object in the object collection. ", 2012, new List<String> { "NYSE", "FTSE" }));
results.Add(new SearchResult(4, "another long piece of title text", -999, new List<String> { "Rabbits", "Chickens" }));
MyDataGrid.AutoGenerateColumns = false;
MyDataGrid.AllowUserToAddRows = false;
MyDataGrid.AllowUserToDeleteRows = false;
MyDataGrid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
MyDataGrid.BackgroundColor = System.Drawing.SystemColors.Control;
MyDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
MyDataGrid.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
MyDataGrid.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.DisplayedCells;
MyDataGrid.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
DataGridViewTextBoxColumn eventIdColumn = new DataGridViewTextBoxColumn();
eventIdColumn.DataPropertyName = "EventId";
eventIdColumn.HeaderText = "Event ID";
eventIdColumn.ReadOnly = true;
eventIdColumn.Width = 84;
DataGridViewTextBoxColumn eventTitleColumn = new DataGridViewTextBoxColumn();
eventTitleColumn.DataPropertyName = "EventTitle";
eventTitleColumn.HeaderText = "Event Title";
eventTitleColumn.ReadOnly = true;
eventTitleColumn.Width = 368;
DataGridViewTextBoxColumn startDateColumn = new DataGridViewTextBoxColumn();
startDateColumn.DataPropertyName = "StartDate";
startDateColumn.HeaderText = "Start Date";
startDateColumn.ReadOnly = true;
startDateColumn.Width = 130;
//I think I need to insert the code for the tags column here, but I'm not sure
MyDataGrid.Columns.Add(eventIdColumn);
MyDataGrid.Columns.Add(eventTitleColumn);
MyDataGrid.Columns.Add(startDateColumn);
//MyDataGrid.Columns.Add(tagsColumn);
MyDataGrid.DataSource = results;
このコードは、オンラインで見つけたチュートリアルから派生させたもので、完全に機能します。
Tags
のプロパティをにバインドしようとしましたがSearchResult
、DataGridViewComboBoxColumn
方法がわかりません。このコードを提供するこの質問を見てきました:
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を使用してデータグリッド全体を一度にバインドします。それは私がこれを行うべき方法ですか?私の状況でそのコードを変更する方法はわかりませんが、これらの線に沿ったものになると思いました。
:
tagsColumn.DataPropertyName = "Tags";
tagsColumn.DisplayMember = ""; // I'm unsure of what to put here
tagsColumn.ValueMember = ""; // Once again, I don't know what to set this to
DataSource
また、列の を設定する行が必要だと思います。
tagsColumn.DataSource = <some LINQ query, perhaps?>
しかし、私が見つけることができた最も関連性の高いC#ソースはその質問だけなので、わかりません。
アップデート:
私は、データバインディングのためにこれに似たコードを提案する2番目の質問を見つけました:
// reference the combobox column
DataGridViewComboBoxColumn cboBoxColumn = (DataGridViewComboBoxColumn)dataGridView1.Columns[0];
cboBoxColumn.DataSource = Choice.GetChoices();
cboBoxColumn.DisplayMember = "Name"; // the Name property in Choice class
cboBoxColumn.ValueMember = "Value"; // ditto for the Value property
それに基づいて、私は a)GetTags()
メソッドをSearchResult
追加し、このコードをDataGridView
初期化コードに追加しました。
DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
tagsColumn.DataSource = SearchResult.GetTags(); // ERROR
tagsColumn.DisplayMember = ""; // Still not sure
tagsColumn.ValueMember = ""; // ??
ただし、これを実行しようとすると、Visual Studio の 2 行目にエラーが表示されます。
An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()'
更新 2:
私はまだ成功せずにこれを探しています。EventId
他のプロパティ (例: ) でデータ プロパティ名を として宣言する方法がわかりません。EventId
これはテーブルに表示されますが、ComboBox
列でこれを行うことはできません。
Tags
オブジェクトは別のクラスでインスタンス化されてリストに入れられるため、プロパティをバインドするためにオブジェクトの配列全体 (数百個ある可能性があります) をループする必要があることは意味がないように思えます。他のプロパティをバインドするためにオブジェクトのリストをループする必要がない場合、各インスタンスのComboBox
列に。SearchResult
EventId
この名前によるプロパティのバインドが一部のプロパティでのみ機能し、他のプロパティでは機能しないのはなぜですか?