2011-01-25 7 views
2

私はDataSetのWindowsフォームアプリケーションを持っています。私は単純にデータ|新しいデータソースを追加してNorthwindデータベースのProductsテーブルをデータソースに追加し、Productsテーブルの内容を示すDataGridViewを作成しました。私は、ProductsテーブルをData Sourcesウィンドウからフォームにドラッグするだけで、すべてのカラムが自動的に作成されます。列DataPropertyNameに基づいてDataRowView内のセルにアクセスする方法?

ここで、Discontinued列が真である製品を含む行を別の色で塗りたいとします。 CellPaintingイベントハンドラを作成しましたが、Discontinuedカラムの値を見つけるのに問題があります。

DataGridViewが自動的に作成されるため、その列の名前はのようになり、DataPropertyNameは「ProductID」です。

私の質問は、DataPropertyNameに基づいて製造中止の値を知る方法はありますか?または、列自体の名前を使用する必要がありますか?

(私は良くそれを意味のある名前を付けた場合には)私のコードは次のとおりです。

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
「あなたはノースウィンドを使用していることを述べてきた、あなたがしたこと単にProductsテーブルをフォームにドラッグするだけなので、これはミッションクリティカルなソフトウェアではないと思っていますが、他の読者の利益のために、これは典型的なアプローチではない実際のアプリケーションではこれ以上は使用できません。

一般的に、我々は、おそらくデータストアから、当社のドメインオブジェクトを取得するためにORMを使用して、Domain Modelを持っ検討したい、これらの日のデータ構造を構築するためにMVVMのようなものを使用して、おそらく、その後、(もちろん、データセットのが本当のORMではありません)これらのドメインオブジェクトからのUI要素へのバインディングに最適化されています。

実際のデータをViewModelに渡すので、実際のデータから色などのルールを計算することができ、UIは単純にそれらのビジネスルールを適用した結果を表示します。

+0

これはかなりのキャスティングです。 DataGridViewRowをDataRowViewにキャストしてから、そのRowプロパティを目的のDataRowタイプにキャストする必要があります。しかし、とにかく、あなたのポストは私を助けました。私は自分のC#の実装を自分のAnswerに追加し、あなたの答えを答えとしてマークします。 – comecme

+0

喜んで助けました。キャストの必要性は残念ですが、私が作ることができる限り、それは必要です。もちろん、キャッシングなどで最適化することもできますが、基本的にはこれを行う方法です。 –

0

reqdColumnIndexがあなたのbool値

+0

問題は、正確に正しい列を見つける方法です。だから私は 'reqdColumnIndex'を知らない。 – comecme

1

はなぜあなたがその特定の列に自分自身を名前を付けてみていないと、あなたはどのように知っているコラムです

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

あなたはこれらの行に何かを試すことができますそれにアクセスする。ビジュアルスタジオは、たとえ自動生成されたとしてもこれに問題はありません。これは、バックグラウンドですべてのバインディングと列作成の作業を手助けするために生成されたものです。 を編集できるのはまだですが、自動生成されたものが実行時に生成されたわけではありません。あなたがいつものものをやってくれるのを手伝ってくれるだけですが、編集することはできます。

row.Cells[ nameOrIndexOfColumn ] 
+0

それは私が「列自体の名前を使用する必要があるのですか?(その場合は意味のある名前を付けるのがよいでしょう)」という意味です。 – comecme

+0

あなたがコーディングの冒険に飛び込みたいのでなければ、単に列に名前をつけてください。 ;-) –

関連する問題