Come ottengo i valori da SelectedItem in ComboBox con Linq e C # 3.5
-
06-07-2019 - |
Domanda
Mi manca davvero qualcosa con tipi anonimi, perché non riesco a capire cosa fare con la proprietà Combobox.SelectedItem.
Ecco il codice che popola la casella combinata e funziona perfettamente
var stocks = from st in brdc.tb_dStocks
join su in brdc.tb_rStockUsers on st.StockID equals su.StockID
where su.UserID == userRec.UserID
select new { st.StockID, su.StockUserID, st.Ticker };
cboStocks.ItemsSource = stocks;
cboStocks.DisplayMemberPath = "Ticker";
Quindi, quando qualcuno seleziona un oggetto usando la combobox di cboStocks devo capire cos'è quell'elemento, ma non ho idea di come farlo. Chiaramente, questo è un problema semplice, ma mi confonde molto. cboStocks.SelectedItem è un oggetto e quell'oggetto è di tipo anonimo creato da Linq, ma è tutto ciò che riesco a capire.
Soluzione
I tipi anonimi sono davvero utili (e dovrebbero essere usati solo) con un metodo. Qui stai creando il tipo in un metodo quando inizializzi la casella combinata e quindi provi ad accedervi in ??un altro durante la lettura dell'elemento selezionato. Questo non funzionerà.
È necessario creare un tipo effettivo da assegnare al ItemsSource
della casella combinata.
Altri suggerimenti
Sfortunatamente, non c'è un buon modo per farlo senza riflessione. I tipi anonimi non sono pensati per essere riposti e recuperati in seguito in assenza di un grande quadro di riflessione per verificarli. Sono praticamente progettati solo per comodità temporanea nei metodi che stanno riorganizzando i dati internamente.
Ti suggerisco di creare un tipo con gli stessi tre campi; quindi è una cosa banale lanciarlo e ottenere ciò che desideri.
Trovato il seguente approccio su questo blog qualche tempo fa, prova quanto segue:
private List<T> MakeList<T>(T itemOftype)
{
List<T> newList = new List<T>();
return newList;
}
//create a fake type for anonymous type
var stockType = new {StockID = 0, StockUserId =0, Ticker = string.Empty};
var listOfStocks = MakeList(stockType);
var listOfStocksAnonymous = from st in brdc.tb_dStocks
join su in brdc.tb_rStockUsers on st.StockID equals su.StockID
where su.UserID == userRec.UserID
select new { st.StockID, su.StockUserID, st.Ticker };
listOfStocks = listOfStocksAnonymous.ToList<stockType>();
//now you have a direct access to all anonymous properties
Sono d'accordo con ChrisF. Dovresti usare un tipo concreto qui. Tuttavia, questa soluzione alternativa funziona se si desidera provarlo:
T Cast<T>(object obj, T type)
{
return (T)obj;
}
...
var myItem = Cast(cboStocks.SelectedItem, new { st.StockID = 0, su.StockUserID = 0, st.Ticker = "" });
...
Quindi ecco cosa ho finito per fare, sembra funzionare abbastanza bene
private class StockInfo
{
public int StockID { get; set; }
public int StockUserID { get; set; }
public string Ticker { get; set; }
public StockInfo(int stockID, int stockUserID, string ticker)
{
StockID = stockID;
StockUserID = stockUserID;
Ticker = ticker;
}
}
BaxRunDataContext brdc = new BaxRunDataContext();
IEnumerable<StockInfo> stocks = from st in brdc.tb_dStocks
join su in brdc.tb_rStockUsers on st.StockID equals su.StockID
where su.UserID == userRec.UserID
select new StockInfo(st.StockID, su.StockUserID, st.Ticker);
cboStocks.ItemsSource = stocks;
cboStocks.DisplayMemberPath = "Ticker";