2011-11-10 24 views
5

Estoy intentando transferir mi aplicación Excel a la cuadrícula de datos de WPF. Voy a ingresar datos en la columna A y en la columna B me gustaría hacer el cálculo tomando la celda previa y la celda actual de la columna A y agregar la celda anterior a la columna B. Ejemplo de cálculo: B2 = B1 + (A2-A1). ¿Cuál es el mejor enfoque para hacerlo?Columnas calculadas de DataGrid

+0

Espera. Solo capté esto. Por "celda anterior" ¿te refieres a la * fila * anterior? –

+0

Sí, celda de la fila anterior de la misma columna. La fila actual es 2, entonces en la celda (B2) me gustaría hacer un cálculo = B1 + (A2-A1) – Jim

Respuesta

4

En lo personal, me gustaría empezar por la creación de una clase que representa los registros y poner en práctica INotifyPropertyChanged en dicha clase.

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

Luego, en su código detrás de la ventana que está mostrando la cuadrícula de datos, tendrá que suscribirse a PropertyChanged en cada objeto en la lista. Entonces tendría que calcular manualmente los valores de la columna cada vez que cambien esas propiedades. Ick, lo sé, pero funcionaría.

La propiedad evento modificado se vería así:

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

Si conecta este evento a todos los registros de la lista de salto, entonces va a disparar siempre que se cambie cualquier propiedad. En la clase anterior, esto se aplicaría tanto a A como a B. Puede filtrar las propiedades que le interesan monitorear a través de e.PropertyName (una simple comparación de cadenas) y evaluar la lógica de negocios en consecuencia. Si desea mantener la encapsulación, o al menos, poner la lógica comercial para el objeto en el objeto mismo, este método podría ser estático en la clase recordObject. Sin embargo, tendrías que prever la obtención de la cuadrícula de datos a partir de ese método estático (probablemente a través de una propiedad estática en tu ventana). Por lo tanto:

public static void recordObject_PropertyChanged(object sender, PropertyChangedEventArgs e) 

y conectado de modo:

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

Guau, esta es una respuesta realmente detallada, gracias por eso. Por lo que yo entiendo, su respuesta se centra en la actualización automática de la Columna B, que es bienvenida, pero no en la etapa actual. Lo que estoy buscando ahora es la lógica de negocios detrás de la escena. – Jim

+0

¿Podría ser más específico, Jim? Todo lo que tienes por lógica de negocios en tu pregunta es B2 = B1 + (A2-A1). Pensé que tu pregunta era más general, así que no estoy seguro de a qué te refieres. –

+1

lo marcaré como respondido, sin embargo tengo que estudiar cosas que sugirió y hacer muchos intentos y errores :) – Jim

4

Lo mejor es implementar esa lógica en una clase y vincular la grilla a las propiedades respectivas. Por ejemplo:

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

Esta solución exacta no funcionaría para lo que se intenta lograr. Cada instancia de SomeData debería tener una referencia a SomeData anterior para calcular B cada vez dependiente de los valores de A y B en los SomeData anteriores. –

+0

Buena captura, Adam. Me había perdido eso en mi respuesta también. –

+0

Gracias, he implementado su solución (Nick y Jacob) para hacer un cálculo en la misma fila sin ningún problema. Sin embargo, todavía no puedo entender cómo obtener la celda de la fila anterior y agregarla a la celda B2 de la fila actual = B1 + (A2-A1) – Jim

Cuestiones relacionadas