// PropertyChanged event for SpreadSheet. // This method is where all the meat is for when a cell gets an input by the user. // The purpose of it is to determine if a user entered an formula or a value. // If it's a formula it uses the ExpTree to calculate the value, and set the cells value to that. // If the user doesn't enter a formula, it sets that cell value and text to what the user entered. // ----------------------------------------------------------------------------- // It's good to point out also how the there is a check to see if the input is valid, // if it's invalid the cell will display "#REF", // Then after the cell gets updated, all the dictionaries get updated accordingly. private void SpreadSheetCell_PropertyChanged(object sender, PropertyChangedEventArgs e) { var currentCell = sender as SpreadsheetCell; ExpTree tree = new ExpTree(variables); List <string> multiDependencies = new List <string>(); // Check if input is valid if (!IsValidInput(currentCell)) { currentCell.SetValue("#REF"); return; } // If the user entered a formula if (currentCell.Text != null && currentCell.Text[0] == '=') { tree.SetExpression(currentCell.Text.Substring(1)); currentCell.SetExpression(currentCell.Text.Substring(1)); currentCell.SetValue(tree.Eval().ToString()); // Gets the new dependencies from the tree, // and in a loop updates the dependency dictionary multiDependencies = tree.GetDependencies(); foreach (string s in multiDependencies) { SpreadsheetCell myCell = GetCell(s); if (!dependencies.ContainsKey(myCell)) { dependencies.Add(myCell, new List <SpreadsheetCell>()); } dependencies[myCell].Add(currentCell); } } // If user enters a value else { // Set value of the cell currentCell.SetValue(currentCell.Text); // Set the expression of that cell to null currentCell.SetExpression(string.Empty); RemoveDependencies(currentCell); } UpdateVariables(currentCell); if (CellPropertyChanged != null) { CellPropertyChanged(sender, e); } UpdateDependencies(currentCell, tree); }
// The purpose of this method is to update the dependencies in the spreadsheet // after a cell gets messed with. It iterates through a list of dependencies (from inside the dependencies dictionary) // and recursively updates all cells that are dependent on that specific cell public void UpdateDependencies(SpreadsheetCell currentCell, ExpTree tree) { // Check if that cell has dependencies if (dependencies.ContainsKey(currentCell)) { // iterate through the list inside dependencies dictionary foreach (SpreadsheetCell c in dependencies[currentCell]) { // Updates the tree's expression tree.SetExpression(c.GetExpression()); // Sets the new value to the new Eval from the tree c.SetValue(tree.Eval().ToString()); CellPropertyChanged(c, new PropertyChangedEventArgs("Value")); // Update variables dictionary UpdateVariables(c); UpdateDependencies(c, tree); } } }