//Used to update a cell's evaluated text value, defined recursively to allow for nested references (e.g. B1 = B2, B2 = B3, B3 = "5") private string changedCellStringContents(AbstractCell cell) { if (cell.TextValue.First() != '=') { return(cell.TextValue); } else { ExpTree expTree = new ExpTree(cell.TextValue.Substring(1)); List <ExpTree.VarNode> variableNodeList = expTree.variablesNodes(); foreach (ExpTree.VarNode varNode in variableNodeList) { int column = ((int)varNode.getName()[0] - 64) - 1; int row = int.Parse(varNode.getName().Substring(1)) - 1; string temp = cells[row, column].EvaluatedValue; if (temp.Length == 0) { return("#REF!"); //Refernce Error } varNode.setValue(Double.Parse(cells[row, column].EvaluatedValue)); } //Unsubscribe from the following Cells foreach (AbstractCell subCell in cell.SubscribedToCells) { subCell.PropertyChangedValue -= (PropertyChangedEventHandler)cell.HandleValuePropertyChanged; } //Executed separately to ensure no cells are subrscribed if a reference error occurs foreach (ExpTree.VarNode varNode in variableNodeList) { int column = ((int)varNode.getName()[0] - 64) - 1; int row = int.Parse(varNode.getName().Substring(1)) - 1; cells[row, column].PropertyChangedValue += new PropertyChangedEventHandler(cell.HandleValuePropertyChanged); //Record which cells we're subbed to cell.SubscribedToCells.Add(cells[row, column]); } return(expTree.Eval().ToString()); //return changedCellStringContents(cells[row, column]); } }