2011-11-10 2 views
5

Sto provando a trasferire la mia app Excel in datagrid WPF. Inserirò i dati nella colonna A e nella colonna B vorrei fare il calcolo prendendo la cella precedente e la cella corrente della colonna A e aggiungere la cella precedente della colonna B. Esempio di calcolo : B2 = B1 + (A2-A1). Qual è l'approccio migliore per farlo?DataGrid colonne calcolate

+0

Aspetta. Ho appena capito questo. Con "cella precedente" intendi nella precedente * riga *? –

+0

Sì, cella della riga precedente della stessa colonna. La riga corrente è 2, quindi nella cella (B2) vorrei fare un calcolo = B1 + (A2-A1) – Jim

risposta

4

Personalmente, mi piacerebbe iniziare con la creazione di una classe che rappresenta i record e implementare INotifyPropertyChanged in quella classe.

public class recordObject : INotifyPropertyChanged 
{ 
    private int a; 
    public int A 
    { 
     get 
     { 
      return a; 
     } 
     set 
     { 
      a = value; 
      OnPropertyChanged("A"); 
     } 
    } 

    private int b; 
    public int B 
    { 
     get 
     { 
      return b; 
     } 
     set 
     { 
      b = value; 
      OnPropertyChanged("B"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Poi, nel codice dietro sulla finestra si sta mostrando il DataGrid, ti consigliamo di iscriverti al PropertyChanged su ogni oggetto nella lista. Quindi dovresti calcolare manualmente i valori delle colonne ogni volta che tali proprietà cambiano. Ick, lo so, ma funzionerebbe.

La proprietà evento modificato sarà simile:

void recordObject_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    var objectList = DataGrid.ItemsSource as List<recordObject>; 
    var myRecord = sender as recordObject; 
    if (objectList != null && myRecord != null) 
    { 
     int idx = objectList.IndexOf(myRecord); 
     // Perform your calculations here using idx to access records before and after the current record 
     // making sure to check for list boundaries for top and bottom. 
     // Also note that this will likely kick off cascading event calls so make sure you're only changing 
     // the previous or following record object. 
    } 
} 

Se si collega questo evento su tutti i record nella lista legato, allora sarà fuoco ogni volta qualsiasi proprietà viene modificata. Nella classe sopra, ciò si applicherebbe sia a A che a B. Puoi filtrare le proprietà a cui sei interessato nel monitoraggio tramite e.PropertyName (un semplice confronto tra stringhe) e controllare la logica di business di conseguenza. Se si desidera mantenere l'incapsulamento, o almeno, inserire la logica di business per l'oggetto sull'oggetto stesso, questo metodo potrebbe essere statico sulla classe recordObject. Dovresti provvedere a procurarti il ​​datagrid da quel metodo statico, sebbene (probabilmente attraverso una proprietà statica sulla tua finestra). Quindi:

public static void recordObject_PropertyChanged(object sender, PropertyChangedEventArgs e) 

e collegati in modo:

record.PropertyChanged += new PropertyChangedEventHandler(recordObject.recordObject_PropertyChanged); 
+0

Wow, questa è una risposta davvero dettagliata, grazie per questo. Per quanto ho capito, la tua risposta si concentra sull'aggiornamento automatico della colonna B, che è benvenuta ma non allo stadio attuale. Quello che sto cercando in questo momento è la logica di business dietro la scena. – Jim

+0

Potresti essere più preciso, Jim? Tutto quello che hai nella logica di business nella tua domanda è B2 = B1 + (A2-A1). Pensavo che la tua domanda fosse più generale, quindi non sono sicuro di cosa stai ricevendo. –

+1

lo contrassegnerò come risposta, tuttavia devo studiare le cose che hai suggerito e fare molti tentativi ed errori :) – Jim

4

La cosa migliore è implementare quella logica in una classe e associare la griglia alle rispettive proprietà. Per esempio:

class SomeData 
{ 
    int A { get; set; } 
    int B { get; set; } 
    int AminusB { get { return A - B; } } 
} 
+1

Questa soluzione esatta non funzionerebbe per ciò che si sta tentando di realizzare. Ogni istanza di SomeData dovrebbe avere un riferimento al precedente SomeData per calcolare B ogni volta in base ai valori di A e B sul precedente SomeData. –

+0

Buona cattura, Adam. Mi ero perso anche nella mia risposta. –

+0

Grazie, ho implementato la soluzione (Nick e Jacob) per effettuare un calcolo sulla stessa riga senza alcun problema. Tuttavia non riesco ancora a capire come ottenere la cella della riga precedente e aggiungerla alla cella corrente B2 = B1 + (A2-A1) – Jim