2011-11-10 11 views
5

Próbuję przenieść moją aplikację Excel do datagridu WPF. Zamierzam wprowadzić dane do kolumny A iw kolumnie B chciałbym wykonać obliczenia biorąc wcześniejszą komórkę i bieżącą komórkę kolumny A i dodać komórkę przedwstępną kolumny B. przykład obliczeniowy: B2 = B1 + (A2-A1). Jakie jest najlepsze podejście do tego?Obliczone kolumny DataGrid

+0

Czekaj. Właśnie to złapałem. Przez "poprzednią komórkę" masz na myśli poprzedni * wiersz *? –

+0

Tak, komórka poprzedniego wiersza tej samej kolumny. Obecny wiersz to 2, więc w komórce (B2) chciałbym wykonać obliczenie = B1 + (A2-A1) – Jim

Odpowiedz

4

Osobiście zacznę od utworzenia klasy reprezentującej rekordy i implementacji INotifyPropertyChanged dla tej klasy.

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

Następnie w kodzie tyłu na oknie jesteś pokazując DataGrid, będziemy chcieli zapisać się do PropertyChanged na każdy obiekt na liście. Następnie trzeba ręcznie obliczyć wartości kolumn, gdy te właściwości się zmienią. Wiem, wiem, ale zadziałałoby.

Obiekt zmienił zdarzenie może wyglądać następująco:

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

Jeśli hak to wydarzenie na wszystkie rekordy w swojej związanego liście, to będzie ogień, gdy wszelkich nieruchomości ulega zmianie. W powyższej klasie dotyczy to zarówno A, jak i B. Możesz filtrować właściwości, które chcesz monitorować za pomocą e.PropertyName (proste porównanie ciągów znaków) i odpowiednio odwzorować logikę biznesową. Jeśli chcesz zachować enkapsulację lub przynajmniej umieścić logikę biznesową dla obiektu na samym obiekcie, ta metoda może być statyczna w klasie recordObject. Trzeba jednak zapewnić przechwycenie datagridu z tej statycznej metody (prawdopodobnie za pośrednictwem statycznej właściwości w oknie). Więc:

public static void recordObject_PropertyChanged(object sender, PropertyChangedEventArgs e) 

i podłączone tak:

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

Wow, to jest naprawdę szczegółowa odpowiedź dzięki za to. O ile zrozumiałem twoja odpowiedź skupia się na automatycznej aktualizacji Kolumny B, która jest mile widziana, ale nie na obecnym etapie. To, czego teraz szukam, to logika biznesowa kryjąca się za sceną. – Jim

+0

Mógłbyś być bardziej konkretny, Jim? Wszystko, co masz w logice biznesowej na swoim pytaniu, to B2 = B1 + (A2-A1). Myślałem, że twoje pytanie jest bardziej ogólne, więc nie jestem pewien, do czego zmierzasz. –

+1

Oznaczę to jako odpowiedź, ale muszę się uczyć rzeczy, które zasugerowałeś i zrobić wiele prób i eros :) – Jim

4

Najlepiej zastosować tę logikę w klasie i związać siatkę z odpowiednimi właściwościami. Na przykład:

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

To dokładne rozwiązanie nie zadziałałoby dla tego, co próbuje się osiągnąć. Każde wystąpienie SomeData będzie musiało mieć odniesienie do poprzednich SomeData w celu obliczenia B za każdym razem w zależności od wartości A i B w poprzednich SomeData. –

+0

Dobry połów, Adam. W mojej odpowiedzi też to przeoczyłem. –

+0

Dzięki, zaimplementowałem Twoje rozwiązanie (Nick i Jacob), aby wykonać obliczenia w tym samym wierszu bez żadnych problemów. Jednak nadal nie mogę zrozumieć, jak uzyskać poprzedni wiersz Komórki i dodać go do bieżącej komórki wiersza B2 = B1 + (A2-A1) – Jim

Powiązane problemy