private void Spreadsheet_PropertyChanged(object sender, PropertyChangedEventArgs e) { if ("Text" == e.PropertyName) //checks if Cell.Text property was changed { string oldValue = ((Cell)sender).Value; //make a copy of the value of the old string for undo methods ICmd temp = new RestoreText((Cell)sender, oldValue); AddUndo(temp); if (((Cell)sender).Text.IndexOf('=') == 0) //must evaluate if it's a formula { //remove cell from every hashset in dependency table to update the dependency table after formula evaluation foreach (KeyValuePair <Cell, HashSet <Cell> > p in dependencies) { dependencies[p.Key].Remove((Cell)sender); } string formula = ((Cell)sender).Text.Replace("=", ""); var tree = new ExpTree(formula); //put the formula in tree for evaluation string[] variables = tree.GetVars(); //get the variables from the tree if (checkValidFormulaVariables(variables) && !checkSelfReference(((Cell)sender), variables)) //check if variables are in valid format { foreach (string s in variables) { double value = getCorrespondingCellValue(s); //get the individual variable value tree.SetVar(s, value); //set the variable so the tree can evaluate the expression updateDependencyTable((Cell)sender, s); } double finalValue = tree.Eval(); //returns the final result of formula evaluation ((Cell)sender).Value = finalValue.ToString(); } else if (!checkValidFormulaVariables(variables)) //variables not in valid format { tree.ClearVariables(); //delete bad variables ((Cell)sender).Text = "!(invalid entry)"; } else { tree.ClearVariables(); ((Cell)sender).Text = "!(self reference)"; } } else //just a constant value or some string was entered { //check if any cells depend on the cell where value was changed and update them if (dependencies.ContainsKey((Cell)sender) && dependencies[(Cell)sender].Count > 0) { foreach (Cell cell in dependencies[(Cell)sender]) { //Re-evaluate the formulas of each cell depending on the changed cell string formula = cell.Text.Replace("=", ""); var tree = new ExpTree(formula); string[] vars = tree.GetVars(); if (checkValidFormulaVariables(vars)) //check if variables are in valid format { foreach (string v in vars) { Cell check = getCorrespondingCell(v); double varValue = 0.0; if (check == ((Cell)sender)) //check if the variable is the cell being changed { double.TryParse(((Cell)sender).Text, out varValue); //set value of that variable to the newly changed value } else { varValue = getCorrespondingCellValue(v); } tree.SetVar(v, varValue); } double finalValue = tree.Eval(); //returns the final result of formula evaluation cell.Value = finalValue.ToString(); } else { cell.Text = "!(invalid entry)"; } } } ((Cell)sender).Value = ((Cell)sender).Text; //set the value of the cell } } if (CellPropertyChanged != null) //does the event have subscribers? { CellPropertyChanged(sender, e); } }