Domanda

Ho associato un ASP.net GridView a una raccolta di tipi anonimi.

Come posso fare riferimento a una delle proprietà dei tipi anonimi nel gestore eventi RowDataBound?

Sono già a conoscenza del modo di trasmettere il tipo anonimo in questo modo:

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

Penso che molti direbbero che è disordinato, anche se funziona. Nel mio codice reale, ho più di 3 proprietà e dovrei aggiornare il codice in due punti ogni volta che ho aggiunto o riordinato le proprietà del mio tipo anonimo.

C'è un modo migliore per dire a e.Row.DataItem che ha una proprietà specifica di un tipo specifico e forzare l'oggetto a darmi quel valore (oltre a creare una classe)?

È stato utile?

Soluzione

Il modo in cui stai usando (cast per esempio) è disordinato e molto fragile - io davvero non lo consiglio (se aggiungi una proprietà o le dai in un ordine diverso, si romperà; ecc.). L'approccio migliore consiste nell'utilizzare il proprio tipo denominato nella proiezione.

Altri suggerimenti

Cerca di usare la riflessione.

Esempio:

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

Controllo degli errori e ottimizzazione lasciati come esercizio al lettore.

Un modo migliore sarebbe quello di creare un tipo per gestirlo in modo da non dover fare tutto quel casting per usare il tipo anonimo.

Quello che faccio è ... ad esempio,

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

... ma questo è in un gestore di eventi ItemDataBound listview. Ho pensato che potesse essere utile per qualcuno.

No, non credo che ci sia un modo migliore di questo. I ragazzi di C # in realtà non supportano l'utilizzo di tipi anonimi al di fuori dell'ambito del metodo locale (ovvero qui hai un tipo anonimo collegato al tuo oggetto Row.)

Il solito suggerimento sarebbe invece di fare una vera classe.

Il metodo che stai usando per lanciare l'oggetto anonimo (anche se molto interessante) è un hack. Funziona semplicemente perché il compilatore C # è abbastanza intelligente da creare solo un'istanza della classe anonima per l'intera app se le proprietà sono uguali. Quindi non c'è davvero alcun vantaggio nell'usare tipi anonimi, dato che una classe viene comunque creata dietro le quinte. Sì, puoi hackerarlo, puoi usare la riflessione, ma seriamente, perché preoccuparsi? Quali sono i vantaggi dell'utilizzo di tipi anonimi in questo caso?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top