Domanda

ho un datagrid popolata da una query LINQ. Quando la riga concentrata nei cambiamenti DataGrid devo impostare una variabile uguale a una delle proprietà di tale oggetto.

ho provato ...

var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject.Id;

... ma il compilatore non si preoccupa per questo a tutti ( "dichiarazione incorporato non può essere una dichiarazione o una dichiarazione etichettati").

Sembra che la proprietà deve essere di facile accesso. Controllo l'oggetto durante il runtime mostra tutte le proprietà che mi aspetto, solo che non so come accedervi.

Come posso ottenere l'accesso alle proprietà dell'oggetto anonimo?

Modifica chiarimenti:

mi capita di essere utilizzando il controllo DevExpress XtraGrid. Ho caricato questo controllo con una query LINQ che era composto di diversi oggetti, rendendo quindi i dati non proprio conforme con qualsivoglia classe I già (cioè, non posso lanciare questo per nulla).

sto usando .NET 3.5.

Quando osservo i risultati del metodo view.GetRow (rowHandle) ottengo un tipo anonimo che assomiglia a questo:

{ ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }

Il mio obiettivo è quello di ottenere il ClientId da questo tipo anonimo in modo da poter fare altre cose (come ad esempio un carico di un modulo con quel record cliente in esso).

Ho provato un paio di suggerimenti nei primi risposte, ma era in grado di arrivare a un punto in cui ho potuto ottenere questo ClientId.

È stato utile?

Soluzione

Avete mai provato ad utilizzare la riflessione? Ecco un frammento di codice di esempio:

// use reflection to retrieve the values of the following anonymous type
var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; 
System.Type type = obj.GetType(); 
int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null);
string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null);

// use the retrieved values for whatever you want...

Altri suggerimenti

Una soluzione generica per ottenere il valore di un elemento di dati per una data chiave

public static T GetValueFromAnonymousType<T>( object dataitem, string itemkey ) {
    System.Type type = dataitem.GetType();
    T itemvalue = (T)type.GetProperty(itemkey).GetValue(dataitem, null);
    return itemvalue;
}

Esempio:

var dataitem = /* Some value here */;
bool ismember = TypeUtils.GetValueFromAnonymousType<bool>(dataitem, "IsMember");

Uno dei problemi con i tipi anonimi è che è difficile usarli tra le funzioni. Non v'è alcun modo per "nome" un tipo anonimo e quindi è molto difficile per lanciare tra di loro. Questo impedisce loro di essere utilizzato come tipo di espressione per tutto ciò che appare nei metadati e viene definita dall'utilizzatore.

Non so dire esattamente quali API si utilizza sopra. Tuttavia non è possibile per l'API per restituire un tipo anonimo fortemente tipizzato quindi la mia ipotesi in quel selectedObject viene digitato da obiettare. C # 3.0 e di seguito non supporta l'accesso dinamico in modo da essere in grado di accedere all'ID proprietà, anche se è disponibile in fase di esecuzione.

Sarà necessario uno dei seguenti per aggirare questo

  • Usa riflessione per afferrare la proprietà
  • Creare un tipo completo e l'uso che per popolare il datagrid
  • Utilizzare uno dei tanti calchi tipo anonimo hacky

Modifica

Ecco un esempio su come fare un hack cast di tipo anonimo

public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { 
  return (T)anonymous;
}

...
object obj = GetSomeAnonymousType();
var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 });

Il motivo è hacky è che è molto facile da rompere questo. Per esempio nel metodo in cui viene originariamente creato il tipo anonimo. Se posso aggiungere un'altra proprietà al tipo lì il codice di cui sopra verrà compilato ma non riescono a runtime.

È possibile utilizzare il tipo dinamico per accedere alle proprietà di tipi anonimi in fase di esecuzione senza l'utilizzo di riflessione.

var aType = new { id = 1, name = "Hello World!" };
//...
//...
dynamic x = aType;
Console.WriteLine(x.name); // Produces: Hello World!

Per saperne di più di tipo dinamico qui: http://msdn.microsoft.com /en-us/library/dd264736.aspx

Quando lavoravo con il passare intorno tipi anonimi e cercando di rifondere loro fine ho trovato più facile scrivere un wrapper che ha gestito lavorare con l'oggetto. Ecco un link ad un post su di esso.

http://somewebguy.wordpress.com/ 2009/05/29 / anonime-tipi-Round-due /

In ultima analisi, il codice sarebbe simile a questa.

//create an anonymous type
var something = new {  
  name = "Mark",  
  age = 50  
};  
AnonymousType type = new AnonymousType(something);

//then access values by their property name and type
type.With((string name, int age) => {  
  Console.Write("{0} :: {1}", name, age);  
}); 

//or just single values
int value = type.Get<int>("age");   

Come JaredPar indovinato, il tipo di ritorno di GetRow() è object. Quando si lavora con la griglia DevExpress, è possibile estrarre il valore desiderato in questo modo:

int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId");

Questo approccio ha aspetti negativi simili come il "tipo hacky anonimo calchi" descritta prima:. Hai bisogno di una stringa magica per identificare la colonna più un tipo di fusione da oggetto a int

xtraGridView

di DevExpress ha un metodo come questo GetRowCellDisplayText (int rowHandle, colonna GridColumn). Con questo metodo, il seguente codice restituisce l'id del tipo anonimo.

var _selectedId = view.GetRowCellDisplayText(rowHandle, "Id");

Anche se questo non fornisce una risposta alla domanda: "Come posso ottenere l'accesso alle proprietà dell'oggetto anonimo?", Si tenta ancora di risolvere la causa principale del problema.

Ho provato questo con Devexpress versione 11.1 e posso vedere che la questione è stato chiesto quasi 2,5 anni fa. Forse l'autore della domanda potrebbe aver ottenuto un workaround o trovato la soluzione se stesso. Eppure, ancora sto rispondendo in modo che possa aiutare qualcuno.

Questo può essere sbagliato (non si può avere abbastanza codice di lì), ma non è necessario per indicizzare nella fila in modo da scegliere la colonna che si desidera? O se "Id" è la colonna che si desidera, si dovrebbe fare qualcosa di simile:

var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject["Id"];

Questo è come mi piacerebbe afferrare il contenuto di una colonna in un DataGrid. Ora, se la colonna è di per sé un tipo anonimo, poi non so, ma se si sta solo ricevendo una colonna denominata con un tipo primitivo, allora questo dovrebbe funzionare.

Spero che questo aiuti, sto passando in un elenco di interfaccia, che ho bisogno di ottenere una lista distinta da. In primo luogo mi appare un elenco di tipo anonimo e quindi io cammino per trasferire alla mia lista degli oggetti.

private List<StockSymbolResult> GetDistinctSymbolList( List<ICommonFields> l )
            {
                var DistinctList = (
                        from a
                        in l
                        orderby a.Symbol
                        select new
                        {
                            a.Symbol,
                            a.StockID
                        } ).Distinct();

                StockSymbolResult ssr;
                List<StockSymbolResult> rl = new List<StockSymbolResult>();
                foreach ( var i in DistinctList )
                {
                                // Symbol is a string and StockID is an int.
                    ssr = new StockSymbolResult( i.Symbol, i.StockID );
                    rl.Add( ssr );
                }

                return rl;
            }

È possibile scorrere le proprietà di un tipo anonimo come questo:

var obj = new {someValue = "hello", otherValue = "world"};
foreach (var propertyInfo in obj.GetType().GetProperties() {
    var name = propertyInfo.Name;
    var value = propertyInfo.GetValue(obj, index: null);
    ...
}

Se si sa cosa si sta facendo e non hanno paura di errori di runtime che ottengono quando le modifiche di codice, si potrebbe lanciare i vostri dati della riga come dynamic:

var data = view.GetRow(rowHandle) as dynamic;  

int clientId      = data.ClientID;
string clientName = data.ClientName;
int jobs          = data.Jobs

Nessuna verifica in fase di compilazione. Ma dovrebbe funzionare bene.

var result = ((dynamic)DataGridView.Rows[rowNum].DataBoundItem).value;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top