2009-03-03 7 views
4

Ich habe eine ASP.net GridView an eine Sammlung anonymer Typen gebunden..net Datenbindung - Verweise auf anonyme Eigenschaften

Wie kann ich auf eine der Eigenschaften der anonymen Typen im RowDataBound-Ereignishandler verweisen?

Ich bin schon von der Art und Weise bewusst die anonyme Art so zu werfen:

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; 
} 

Ich denke, die meisten würden sagen, das ist etwas chaotisch, auch wenn es funktioniert. In meinem echten Code habe ich mehr als 3 Eigenschaften und müsste den Code an zwei Stellen aktualisieren, wenn ich die Eigenschaften meines anonymen Typs hinzugefügt oder neu geordnet habe.

Gibt es eine bessere Möglichkeit, e.Row.DataItem mitzuteilen, dass es eine bestimmte Eigenschaft eines bestimmten Typs hat und das Objekt zwingt, diesen Wert anzugeben (neben dem Erstellen einer Klasse)?

Antwort

3

Die Art und Weise (Guss mit gutem Beispiel) verwenden, ist chaotisch und sehr spröde - ich wirklich würde es nicht empfehlen (wenn Sie eine Eigenschaft hinzufügen, oder benennen Sie sie in einer anderen Reihenfolge, wird es brechen ; etc). Der bessere Ansatz besteht darin, in der Projektion einen eigenen benannten Typ zu verwenden.

+0

Wie meinst du 'benennen sie in einer anderen Reihenfolge?Bedeutet das, dass ein anonymer Typ layout-sensitiv ist (wie eine Struktur)? – leppie

+0

IDK wenn eine Struktur ist oder nicht, aber ja. Wenn ich eine dieser Eigenschaften hinzufüge, entferne, umbenenne oder neu anordne, funktioniert der Cast NICHT. –

+0

Wow, ich habe gerade nach mir selbst gesucht! Ich frage mich, wie ich das verpasst habe? :) – leppie

5

Ein besserer Weg wäre, einen Typ zu erstellen, mit dem man umgehen kann, so dass man nicht all diesen Casting machen muss, um den anonymen Typ zu verwenden.

7

Mit Reflektion untersuchen.

Beispiel:

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! :) 
} 

Fehlerüberprüfung und Optimierung für den Leser als Übung.

+0

Bitte geben Sie spezifische Beispiele dazu an. Ich habe diese Frage mit Reflektion markiert, weil ich das Gefühl hatte, ich könnte Reflektion benutzen. Aber ich weiß nicht genau, was ich machen soll. Vielen Dank. –

+0

Danke für das Beispiel. Ich werde es ausprobieren, obwohl ich wahrscheinlich dafür nur eine Klasse erstellen werde. –

+0

+1 für die Übung zum Leser – Homer

1

Nein, ich glaube nicht, dass es einen besseren Weg gibt. Die C# -Typen unterstützen nicht die Verwendung von anonymen Typen außerhalb des lokalen Methodenbereichs (d. H. Hier ist ein anonymer Typ an Ihr Row-Objekt angehängt).

Der übliche Vorschlag wäre stattdessen, eine echte Klasse zu erstellen.

0

Die Methode, mit der Sie das anonyme Objekt (wenn auch sehr cool) darstellen, ist ein Hack. Es funktioniert einfach, weil der C# -Compiler intelligent genug ist, nur eine Instanz der anonymen Klasse für die gesamte App zu erstellen, wenn die Eigenschaften identisch sind. Es gibt also keinen Vorteil bei der Verwendung von anonymen Typen, da sowieso eine Klasse hinter den Kulissen erstellt wird. Ja, Sie können es hacken, Sie können Reflexion verwenden, aber seriosuly, warum stören? Welchen Vorteil hat die Verwendung anonymer Typen in diesem Fall?

+0

"C# Compiler ist schlau genug" - nun, die Spezifikation garantiert dieses Verhalten, aber ich stimme zu, es ist brüchig und keine gute Idee. –

+0

Nun, es garantiert es, Sie haben Recht, aber selbst der geringste Unterschied, wie sagen Sie die Eigenschaften neu anordnen, und es wird bereits einen neuen Typ für Sie erstellen. So ist es schlau, aber nicht so schlau :) – BFree

+0

Ich stimme völlig mit Ihrem Punkt überein - ich weise nur darauf hin, dass es die Spezifikation ist, nicht der Compiler, der dies tut. Manchmal ist dies wichtig, da es aufgrund eines Implementierungsdetails nicht einfach funktioniert. –

4

Was ich tue, ist ... zum Beispiel

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

... aber das ist in einer Listenansicht ItemDataBound Event-Handler. Dachte, es könnte für jemanden nützlich sein.

+0

+1 Gefällt mir dies. Funktioniert dann auf jedem Objekt? Funktioniert in RowDataBound auf GridView mit DataBinder.Eval (e.Row.DataItem, "JobId") – Andez