2009-03-03 59 views
4

匿名型のコレクションにASP.net GridViewをバインドしました。.netデータバインディング - 匿名型のプロパティの参照

RowDataBoundイベントハンドラで匿名型のプロパティのいずれかを参照するにはどうすればよいですか?

私はすでにこのような匿名型をキャストする方法を知っています:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
     var AnonObj = Cast(e.Row.DataItem, 
      new { StringProperty = "", BoolProperty = false, IntProperty = 0 }); 

     if (AnonObj.BoolProperty) 
     { 
      e.Row.Style.Add(HtmlTextWriterStyle.Color, "Red"); 
     } 
    } 
} 


T Cast<T>(object obj, T type) 
{ 
    return (T)obj; 
} 

私はほとんどこれは、それが仕事をしていても、厄介であると言うだろうと思います。実際のコードでは3つ以上のプロパティがあり、匿名型のプロパティを追加または並べ替えるたびに、2つの場所でコードを更新する必要がありました。

e.Row.DataItemに特定のタイプの特定のプロパティがあることを伝え、そのオブジェクトに(クラスの作成以外に)その値を与えるように強制するのが良い方法はありますか?

答えて

3

(例でキャスト)を使用している方法が乱雑であると非常に脆性 - 私は本当には、プロパティを追加する場合(それをお勧めします、または異なる順序でそれらに名前を付けていない、それは破りますよ;等)。より良いアプローチは、独自の名前付きタイプを投影に使用することです。

+0

あなたはどういう意味ですか?別の順序で?これは、匿名型が(構造体のような)レイアウトに影響を受けていることを意味しますか? – leppie

+0

構造体が存在するかどうかにかかわらず、IDK。それらのプロパティーを追加、削除、名前変更、または並べ替えると、キャストは機能しません。 –

+0

うわー、私はちょうど自分自身をチェック!どのように私はそれを逃したのだろうか? :) – leppie

5

これを処理する型を作成する方が良い方法は、匿名型を使用するためにそのすべてのキャストを行う必要はありません。

7

反射を使用して調べます。

例:読者への課題として残し

object o = e.Row.DataItem; 
Type t = o.GetType(); 
PropertyInfo pi = t.GetProperty("StringProperty"); 
if (pi != null && pi.PropertyType == typeof(string)) 
{ 
    // the property exists! 
    string s = pi.GetValue(o, null) as string; 
    // we have the value 
    // insert your code here 
    // PROFIT! :) 
} 

エラーチェックと最適化。

+0

具体的な例を挙げてください。私は反射を使用することができたと感じていたので、この質問に反射を付けました。しかし、私は何をすべきか正確にはわかりません。ありがとう。 –

+0

ありがとうございます。私はおそらくこれのためのクラスを作成するにしても、私はそれを試してみるつもりです。 –

+0

読者への運動のための+1 – Homer

1

いいえ、私はこれより良い方法はないと思います。 C#のメンバーは、ローカルメソッドスコープの外で匿名の型を使用することは実際にはサポートしていません(ここでは、Rowオブジェクトに匿名型が添付されています)。

通常の代わりに実際のクラスを作ることです。

0

匿名オブジェクトをキャストするために使用している方法(非常にクール)はハックです。これは、C#コンパイラが、プロパティが同じであればアプリ全体の匿名クラスのインスタンスを1つだけ作成するほどスマートなので単純に機能します。とにかく舞台裏でクラスが作成されているので、匿名型の使用には実質的に利点はありません。はい、あなたはそれをハックすることができます、あなたは反射を使用することができますが、seriosuly、なぜ気になる?この場合、匿名タイプを使用するとどのようなメリットがありますか?

+0

"C#コンパイラは十分にスマートです" specはこの動作を保証しますが、私はそれが脆く、良い考えではないことに同意します。 –

+0

それはあなたが正しいと保証しますが、プロパティの順序を変更すると言ったようなわずかな違いもあります。すでに新しいタイプが作成されています。それはスマートですが、スマートではありません:) – BFree

+0

私は完全にあなたの意見に同意します - 私はそれが仕様であり、これはコンパイラではないことを指摘しています。時には、これは重要です。つまり、実装の詳細のために単純に作業しているわけではありません。 –

4

私は何をやっていることは、例えば...

string Name = (string)DataBinder.Eval(dataItem.DataItem, "Name"); 

です...しかし、これは、リストビューItemDataBoundイベントハンドラです。それは誰かにとって役に立つかもしれないと思った。

+0

+1これが好きです。どんなオブジェクトでも動作しますか? DataBinder.Eval(e.Row.DataItem、 "JobId")を使用してGridViewのRowDataBoundで動作します。 – Andez

関連する問題