Datagrid wpf

martedì 21 giugno 2011 - 05.25

brux88 Profilo | Newbie

ciao a tutti qualcuno saprebbe dirmi come inserire cancellare mdoificare record in una datagrid(la fonte dati e in sql server)

freeteo Profilo | Guru

Ciao Brux88,
diciamo che la datagrid non è altro che una visualizzazione di qualcosa in memoria, tipicamente una Collection<T> dove T sono Oggetti che arrivano da qualche connessione al db, file su disco, ciclo in memoria etc... oppure ancora più banalmente una DataTable che arriva da qualche database (anche qui potrebbe essere fatta anche in memoria etc...)

Perciò diciamo che dovresti avere del codice che agisce sulla collection piuttosto che preoccuparti della datagrid, che invece Bindata tramite "ItemsSource" non fa altro che visualizzare quella collection.


Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

ho utilizzato la ObservableCollection e giusto?? pero mi da un problema quando dopo aver effetuato la ricerca vorrei fare un inseirmento e nn sono riuscito a capire il perche:

private fatturaEntities ctx; public ObservableCollection<corpo> cr2; public MainWindow() { InitializeComponent(); this.ctx = new fatturaEntities(); this.cr2 = new ObservableCollection<corpo>(); grdCorpo.ItemsSource = cr2; } private void btnInserisci_Click(object sender, RoutedEventArgs e) { this.grdCorpo.IsEnabled = true; corpo cr = new corpo(); this.ctx.AddTocorpo(cr); this.cr2.Add(cr); // grdCorpo.ItemsSource = cr2; } private void btnRicerca_Click(object sender, RoutedEventArgs e) { //ricerca per id try { int ric = Convert.ToInt32(txtricerca.Text); var loadedLog = ctx.corpo.Where(ent => ent.idcorpo == ric).ToList(); grdCorpo.ItemsSource = loadedLog; } catch (Exception ex) { MessageBox.Show(ex.Message); } }

freeteo Profilo | Guru

>ho utilizzato la ObservableCollection e giusto??
dipende, potresti anche usare una List<T> ad esempio, ma la Observable<T> implementa INotifyCollectionChanged e INotifyPropertyChanged quindi quando la modifichi lei "segnala" i controlli bindati che si aggiornino, perciò sicuramente è una comodità.


>pero mi da un problema quando dopo aver effetuato la ricerca vorrei fare un
>inseirmento e nn sono riuscito a capire il perche:
che errore ti da?

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

si infatti ho letto diversi articoli ed ora ho capito la differenza invece sto trovando difficolta ad effettuare delle operazioni matetmatiche nelle colonne

freeteo Profilo | Guru

>si infatti ho letto diversi articoli ed ora ho capito la differenza
ok


>invece sto trovando difficolta ad effettuare delle operazioni
>matetmatiche nelle colonne
in che senso? Siccome hai oggetti, ti può essere utile fare delle proprietà aggiuntive che ti facciano il calcolo, ad esempio:
public int Guadagno { get { return Ricavi - Spese; } } ... public int Ricavi { get; set; } public int Spese { get; set; } ...

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

si ad esempio l'utente in una griglia(corpo) aggiunge una riga dove mette il numero colli e il peso netto appena inserisce nella clonna prezzo il valore dovrebbe darmi il risultato(prezzo * peso netto) in un altra colonna(importo) della medesima riga della datagrid...come faccio? quando utilizzavo foxpro era smeplicissimo basta che moltiplicavo il controlsource della della riga e ottenvo il risultato sicocme qui si lavora ad oggetti come dovre prendere e far mpoltiplicare quei due valori della stessa riga? non so se sono stato chiaro spero di si =)

freeteo Profilo | Guru

Ciao,
come ti dicevo prima ti basta fare delle proprietà aggiuntive dell'oggetto che ti facciano il calcolo.
Ti ho allegato un esempio velocissimo di quello che intendo, nota la classe OrdineItem e la sua proprietà "Prezzo" che è appunto data dal calcolo sulle altre 2...

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

grazie gentilissimo ho dato un occhiata pero non riesco a capire quando utilizza la proprieta costo perche se in quella griglia modifico il prexxo o il peso netto o aggiungo una irga e inseriso ci dati non mi modifica l'importo =(

freeteo Profilo | Guru

Ciao,
se guardi "a codice" la proprietà "Costo" di fatto cambia (perchè appunto nel "get" della proprietà lui rifà sempre il calcolo) ma la griglia non rilegge quel valore.
Per far sì che la griglia si aggiorni, bisogna che l'oggetto implementi INotifyPropertyChanged ossia segnali al controllo che è da rileggere quella proprietà...nella classe OrdineItem quindi ti basta scrivere qualche riga in più per implementare questa interfaccia:
public class OrdineItem : OggettoBase , INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; void RaiseChanged(string proprieta) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(proprieta)); } DateTime data; public DateTime Data { get { return data; } set { data = value; RaiseChanged("Data"); } } decimal prezzo; public decimal Prezzo { get { return prezzo; } set { prezzo = value; RaiseChanged("Prezzo"); RaiseChanged("Costo"); } } decimal pesoNetto; public decimal PesoNetto { get { return pesoNetto; } set { pesoNetto = value; RaiseChanged("PesoNetto"); RaiseChanged("Costo"); } } public decimal Costo { get { return PesoNetto * Prezzo; } } }

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

ok ora la tua griglia mi funziona per io che ho una griglia che preleva i dati dal databese e tramite itemsource la collego alla mia collezione dati quando l'utente scrive nei campi come faccio a collegare quei metodi esterni?

freeteo Profilo | Guru

>ok ora la tua griglia mi funziona per io che ho una griglia che
>preleva i dati dal databese e tramite itemsource la collego alla
>mia collezione dati quando l'utente scrive nei campi come faccio
>a collegare quei metodi esterni?
purtroppo da anni ormai, preferisco farmi il mio modello e poi collegarlo al db (entity framework sopra a tutti, ma può andare bene anche linq2sql etc..), quindi non ho mai la "vista diretta" del ritorno di una query ma sempre oggetti.

Al posto di questi 2 tools che ti ho menzionato, altre volte uso farmi i miei provider che fanno accesso al db da codice, ma poi di fatto mappo i campi del db su degli oggetti in modo da portarmi sempre e solo (o quasi "solo") su un modello ad oggetti.
Per intenderci, un codice di questo tipo:

public class ClienteDataProvider { public IEnumerable<Cliente> GetAll() { List<Cliente> lista = new List<Cliente>(); using (SqlConnection cn = new SqlConnection(....)) { SqlCommand cmd = cn.CreateCommand(); cmd.CommandText = "SELECT ... FROM..."; cn.Open(); SqlDataReader rd = cmd.ExecuteReader(); while(rd.Read()) lista.Add(BuildCliente(rd)); } return lista; } private Cliente BuildCliente(SqlDataReader rd) { Cliente c = new Cliente(); c.Id = Convert.ToInt32(rd["nomecampoID"]); c.Nome = Convert.ToString(rd["nomecampoNome"]); .... etc ... return c; } ... }

e poi nel codice uso questa classe per chiedere a lei la lista degli oggetti da dare in pasto ai controlli grafici...

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo

brux88 Profilo | Newbie

ciaoo allora finalmente son riuscito ad effettuare la mia fattura tramite il pattenr model view view model sono riusciro a fare le operazioni crud sia nella testat che nella griglia tutto tramite mvvm (anche se ancora non riesco a modifcare le propieta delle griglie ad esempio renderla abilitata tramit eil mvvm ci sto ancora studiando) ora stavo rivedendo di nuovo la situazione per effettuare operazioni matematiche ho adotatto il metodo che in precedenza mi hai allegato e funziona anche se pero il risultato non me lo da subito devo cliccare due volte sulla colonna dell'importo e non capisco il motivo =( poi come dovrei gestrmi tutti i calcoli della riga, siccome ho utilizzato l'entity framewrok che mi ha gia generato in automatico una classe(model1.designers.cs) dov e all'interno ci sono le varie propietà:


[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] [DataMemberAttribute()] public Nullable<global::System.Int32> pnetto { get { return _pnetto; } set { OnpnettoChanging(value); ReportPropertyChanging("pnetto"); _pnetto = StructuralObject.SetValidValue(value); ReportPropertyChanged("pnetto"); OnpnettoChanged(); } } private Nullable<global::System.Int32> _pnetto; partial void OnpnettoChanging(Nullable<global::System.Int32> value); partial void OnpnettoChanged(); [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] [DataMemberAttribute()] public Nullable<global::System.Int32> prezzo { get { return _prezzo; } set { OnprezzoChanging(value); ReportPropertyChanging("prezzo"); _prezzo = StructuralObject.SetValidValue(value); ReportPropertyChanged("prezzo"); OnprezzoChanged(); } } private Nullable<global::System.Int32> _prezzo; partial void OnprezzoChanging(Nullable<global::System.Int32> value); partial void OnprezzoChanged(); [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)] [DataMemberAttribute()] public Nullable<global::System.Int32> imp { get { return _imp; } set { OnimpChanging(value); ReportPropertyChanging("imp"); _imp = StructuralObject.SetValidValue(value); ReportPropertyChanged("imp"); OnimpChanged(); } } private Nullable<global::System.Int32> _imp; partial void OnimpChanging(Nullable<global::System.Int32> value); partial void OnimpChanged();

ora volevo sapere ma se io devo fare prezzo per pnetto devo modificarle all'interno della classe autogenerata da entityframework oppure nella mia classe fatturaviewmodel che ho creato manualmente ?

freeteo Profilo | Guru

>ora volevo sapere ma se io devo fare prezzo per pnetto devo modificarle all'interno della classe autogenerata da >entityframework oppure nella mia classe fatturaviewmodel che ho creato manualmente ?
dovrebbe essere partial la classe che EF ti genera, puoi dichiararne una tu sempre partial con quella proprietà e invocare il ReportPropertyChanged.
Attento però che il tuo problema è che devi farlo nella modifica delle altre 2 proprietà che hai usato nella formula, perchè come ti avevo messo nell'esempio, il calcolo era solo in get (quindi readonly) ma per dire alla griglia in questo caso di refreshare la casella rileggendo il valore sottostante lo devi fare quando cambia uno dei 2 operandi, quindi di fatto nel "set" delle altre 2 proprietà...

Ciao.

Matteo Raumer
[MCAD .net, MVP Visual C#]
http://blogs.dotnethell.it/freeteo
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5