2011-01-25 63 views
2

我有一個Windows窗體應用程序與DataSet。我簡單地使用了Data |添加新數據源以將羅斯文數據庫的產品表添加到我的數據源,並創建一個顯示產品表內容的DataGridView。我只是將Products表從Data Sources窗口拖到表單中,所有列都是自動創建的。如何根據DataPropertyName列訪問DataRowView中的單元格?

現在,我希望包含產品的行的Discontinued列爲true,以不同的顏色繪製。我爲它創建了一個CellPainting事件處理程序,但我在查找Discontinued列的值時遇到了問題。

因爲DataGridView被自動創建,在它的列都有名稱,像dataGridViewTextBoxColumn1,其中有「產品ID」的DataPropertyName

我的問題是:如何根據DataPropertyName找到Discontinued的值?或者我需要使用列本身的名稱? (在這種情況下,我最好給它一個有意義的名字)

我的代碼是:

private void productsDataGridView_CellPainting(object sender, 
    DataGridViewCellPaintingEventArgs e) 
{ 
    if (e.RowIndex >= 0) 
    { 
     var row = productsDataGridView.Rows[e.RowIndex]; 
     if ((bool) (row.Cells[ nameOrIndexOfColumn ].Value)) 
     { 
      e.CellStyle.ForeColor = Color.DarkGray; 
     } 
    } 
} 

我如何可以訪問塔塔DataPropertyName「停產」的價值呢?


解決方案

基於尼爾·巴恩韋爾的答案,這似乎是一種方式。

private void productsDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) 
{ 
    if (e.RowIndex >= 0) 
    { 
     var productView = (DataRowView) productsDataGridView.Rows[e.RowIndex].DataBoundItem; 
     var product = productView.Row as NorthwindDataSet.ProductsRow; 
     if (product != null && product.Discontinued) 
     { 
      e.CellStyle.ForeColor = Color.DarkGray; 
     } 
    } 
} 

這樣做的一大優點是Discontinued值不必是DataGridView上的實際列。

回答

1

不要從網格中的列中獲取值,從填充網格行的實際數據行中獲取值。這樣就可以避免所有的魔法串等

有鑄造工作要做,因爲[Type]DataRow被隱藏的附加到網格中DataView裏面的一點點,但它是一個更好的方法(和少得多的脆性在未來的變化情況下),如果你很好地把它集成到你的代碼中,而不是依靠魔術字符串。

這裏是我的一個老的博客貼子,詳細介紹瞭如何做到這一點:

http://koder.wordpress.com/2010/04/09/getting-data-from-a-winforms-datagridview/

UPDATE
你提到您正在使用Northwind和你已經「只是簡單地將產品表拖到了表單中「,所以我猜這不是一個關鍵任務軟件,但是爲了其他人的閱讀好處,我只是想表明這不是一個典型的方法任何更多的實際應用。

通常這些日子裏,我們會考慮有Domain Model,也許使用ORM獲得我們從數據存儲域對象(當然數據集是不是一個真正的ORM),則可能使用像MVVM的東西來構建數據結構針對綁定到來自這些域對象的UI元素進行了優化。

使用這種方法,因爲您有實際的數據來處理ViewModel,所以您可以從真實數據中計算顏色等規則,並且UI僅顯示應用這些業務規則的結果。

+0

那麼,這是相當有點鑄造發生。首先必須將DataGridViewRow轉換爲DataRowView,然後將其Row屬性轉換爲所需的DataRow類型,這太糟糕了。但無論如何,你的帖子肯定幫了我。我會將我的C#實現添加到我的答案中,並將答案標記爲答案。 – comecme 2011-01-25 12:07:07

+0

很高興幫助。演員的需要是一種恥辱,但據我所知,這是必要的。當然你可以通過緩存等優化它,但實質上這是要採取的方法。 – 2011-01-25 12:16:40

0

您可以嘗試在這些線路上的東西

if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == "Discontinued") 
{ 
    if (dataGridView1[reqdColumnIndex, e.RowIndex].FormattedValue as bool) 
    { 
    e.CellStyle.ForeColor = Color.Gray; 
    } 
} 

reqdColumnIndex是有你的布爾值的列

+0

問題是如何找到正確的列。所以我不知道`reqdColumnIndex`。 – comecme 2011-01-25 12:04:29

1

你爲什麼不試着給一個名稱到特定的列自己,那麼你知道如何訪問它。即使它的自動生成,Visual Studio也不應該有任何問題。因爲它是爲了幫助您在後臺執行所有綁定和列創建工作而生成的。 它仍然是可用於編輯,自動生成並不意味着它在運行時生成。它只是幫助你做平常的事情,但你仍然可以編輯它。

row.Cells[ nameOrIndexOfColumn ] 
相關問題