4

いくつかのプロパティを持つカスタム オブジェクトがあり、そのうちの 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のプロパティをにバインドしようとしましたがSearchResultDataGridViewComboBoxColumn方法がわかりません。このコードを提供するこの質問を見てきました:

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;

私が問題を抱えている理由は、リンクされた質問のいくつかのニュアンスが理解できないためです。

  1. ドキュメントとリンクされた質問によるとDisplayMember、「インスタンスの説明を含む」プロパティにリンクする必要がありますが、SearchResultオブジェクトは動的に追加され、説明が関連付けられていないため、空白のままにしておく必要がありますか?
  2. ValueMemberドキュメントを読んだ後でも何を入れればよいかわからないため、同様の問題が発生しています。
  3. リンクされた質問では、受け入れられた回答が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列に。SearchResultEventId

この名前によるプロパティのバインドが一部のプロパティでのみ機能し、他のプロパティでは機能しないのはなぜですか?

4

2 に答える 2

3

DataGridViewComboBoxColumn要素のリストを表示するために使用する理由がよくわかりません。この列の種類は、ユーザーが多くの可能性から 1 つを選択できるように設計されています。public string SelectedTag{get;set;}あなたはそれを保管するための財産を持っていないので、それはあなたのケースではないようです. あなたのモデルを理解しているように、すでに多くのタグが選択されてSearchResultおり、それらをグリッドに表示したいと考えています。

ドキュメントの状態: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.datasource

この [ DataSource ] プロパティを取得または設定すると、CellTemplate プロパティによって返されるオブジェクトの DataSource プロパティを取得または設定します。このプロパティを設定すると、列のすべてのセルの DataSource プロパティも設定され、列の表示が更新されます。個々のセルに指定された値を上書きするには、列の値を設定した後でセルの値を設定します。

DataGridViewComboBoxColumn には、データ グリッドのすべての行のデータ ソースとして使用される要素のリストが 1 つだけあると想定されているため、items プロパティをデータ ソースにバインドする機能がありません。

ReadOnly = trueまた、他のすべての列と同様に、この列のプロパティを設定すると仮定します。その場合、ドロップダウンリストが表示されないため、ユーザーフォームにタグのリストが表示されなくなります。

文字列のリストを読み取り専用モードで表示したい場合は、このタグのリストを単一の文字列にフラット化することをお勧めします。

public string Tags { get { return string.Join(", ", tags); } }

テキスト列に表示します。

于 2012-07-05T10:46:10.247 に答える
1

エラーについては、クラスのインスタンスを作成してからメソッドを非静的として呼び出すか、メソッドを静的にすることをお勧めします。

さらに、コンボボックス列が必要なため、

DataGridViewComboBoxColumn tagsColumn = new DataGridViewComboBoxColumn();
        tagsColumn.DataSource = SearchResult.GetTags(); // ERROR 
        tagsColumn.DisplayMember = ""; // Still not sure
        tagsColumn.ValueMember = ""; // ??

ほとんどの場合、Country(id,name) のようなオブジェクトのドロップダウンがあるため、DisplayMember = name はドロップダウンにテキストとして表示され、ValueMember = id はデータベース内の参照テーブルで使用されます。しかし、これはあなたの場合ではありません。

ここには dropdown に表示する文字列のリストがあるので、設定する必要はありません。ここに書いてある通り

DataSource プロパティが文字列配列に設定されている場合、配列内の各文字列が値と表示の両方に使用されるため、ValueMember と DisplayMember を設定する必要はありません。

于 2012-06-29T21:13:08.973 に答える