2012-06-29 58 views
2

我有一個自定義對象與幾個屬性,其中之一返回一個列表。這是該對象的代碼:如何將DataGridViewComboBoxColumn綁定到返回列表的對象的屬性/方法?

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對象將顯示在其自己的行中,並且我希望在每個對象的Tags屬性中的List<String>顯示在該行的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; 

我得出這個代碼a tutorial I found online,和它完美的作品。

我一直在試圖將SearchResultTags屬性綁定到DataGridViewComboBoxColumn,但我不確定如何。我一直在尋找this question,它提供了這樣的代碼:

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. 根據the documentation,以及相關的問題,DisplayMember應該鏈接到「包含實例的說明」的屬性,但由於SearchResult對象動態添加或不具有與它們相關的任何說明,應我只是把它留空?
  2. ValueMember給了我類似的問題,因爲即使在閱讀its documentation後,我仍然不確定要放什麼。
  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#源代碼,我已經能夠找到這個問題。

UPDATE:

我發現a second question這表明數據綁定類似下面的代碼:此基礎上

// 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 

,我一個)的添加GetTags()方法SearchResult,並將此代碼到我的DataGridView初始化代碼:

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

但是,Visual Studio的給我上的S錯誤當我嘗試運行此的Econd行:

An object reference is required for the non-static field, method, or property 'SearchResult.GetTags()' 

更新2:

我還在摸索這個沒有成功。我不明白如何與其他屬性(例如EventId)我可以簡單地聲明數據屬性名稱爲EventId,它將顯示在表中,但我不能這樣做與ComboBox列。

由於對象是在一個單獨的類中實例化並放入一個列表中,所以我不應該通過整個對象數組(其中可能有幾百個)進行循環,將Tags屬性綁定到每個實例的ComboBox列,當我不需要遍歷SearchResult對象的列表來綁定其他屬性,例如EventId

爲什麼此綁定屬性的名稱只適用於某些屬性而不是其他屬性?

+1

錯誤來自您調用SearchResult.GetTags();您需要將其設爲靜態方法,或者首先實例化SearchResult(新...) – blearn

+0

@blearn在第二個鏈接問題的答案中,該對象未實例化。另外,由於'SearchResult'對象會動態地添加到這個列表中,所以在一個單獨的類中的方法中,除非我遍歷它們,否則我不一定能夠訪問它們,在這種情況下,我可能只是跳過數據綁定,手動填充'DataGridView',我試圖避免這麼做。 –

回答

3

我不太明白你爲什麼要用DataGridViewComboBoxColumn來顯示元素列表。此列種類旨在允許用戶選擇多種可能性之一。它接縫它不是你的情況,因爲你沒有public string SelectedTag{get;set;}屬性來存儲它。據我瞭解您的模型,您已爲SearchResult選擇了許多標籤,並且希望以網格顯示它們。

如文檔狀態: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxcolumn.datasource

獲取或設置該[的DataSource]屬性獲取或設置由CellTemplate屬性返回的對象的數據源屬性。設置此屬性還會將該列中的每個單元格的數據源屬性設置爲,並刷新列顯示。要覆蓋單個單元格的指定值,請在設置列值後設置單元格值。

DataGridViewComboBoxColumn根本沒有將項目屬性綁定到數據源的功能,因爲它假定只有一個元素列表被用作所有數據網格行的數據源。

我還假設您將爲此列設置ReadOnly = true屬性,就像您對其他所有屬性一樣。如果是這樣,它會阻止用戶形式看到標籤列表,因爲下拉列表永遠不會顯示。

如果你的魔杖,顯示在只讀模式字符串列表,我建議扁平化的標籤,以單個字符串此列表:

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

和文本列顯示。

+0

我原本想這樣做,因爲我不確定是否有其他方法,但是最終我使用了與您發佈的代碼類似的東西(使用'Join')並創建了自己的用戶控件。 –

1

對於錯誤,我可以建議你做一個類的實例,然後調用該方法,因爲它不是靜態的,或者你可以使你的方法是靜態的。

而且當你需要comboboxcolumn,

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

主要是我們有類似的對象下拉菜單中國家(ID,姓名),所以DisplayMember =名稱將顯示在下拉列表的文本,而ValueMember = ID將被使用數據庫中的引用表。但這不是你的情況。

在這裏你有一個字符串列表顯示在下拉列表中,所以你不需要設置它們。 作爲書面here

當dataSource屬性被設置爲一個字符串數組,然後ValueMember 和DisplayMember不需要被設置,因爲 陣列中的每個字符串將被用於兩個值和顯示。

+0

除了使用對象的實例之外,沒有其他方法可以做到這一點嗎?我不能像其他房產一樣自動做到這一點?看到我對原始問題的評論。 –

相關問題