private string solver(string equation) { ExpTree mytree = new ExpTree(equation); findCells(mytree); return(mytree.Eval().ToString()); }
private string CalculateValue(string text, SpreadsheetCell senderCell) { text = text.Substring(1); //removes the first character of the string, which is = if (text.Length > 1) //if there are variables to replace, they will be at least 2 chars { MatchCollection splitOperands = Regex.Matches(text, @"\w+\.?\d*"); //temporary way to get all the variables. HashSet <SpreadsheetCell> referencedCells = new HashSet <SpreadsheetCell>(); foreach (Match mat in splitOperands) { if (!Regex.Match(mat.Value, @"^\d+").Success) // if the match starts with a number then its not a coordinate and we dont have to retrieve a value. { SpreadsheetCell cell = GetCell(mat.Value) as SpreadsheetCell; cell.ValueChanged += senderCell.OnValueChanged; senderCell.AddReferenceToCell(cell); //tell the sender cell what its referencing. Hashsets can only have unique values, so adding something that is already here will do nothing. referencedCells.Add(cell); //keep track of which cells this specific expression looks for. text = text.Replace(mat.Value, cell.Value); //replaces that substring in the text with that cell's value. } } referencedCells.SymmetricExceptWith(senderCell.ReferencedCells); //removes all the cell references that are the same. foreach (SpreadsheetCell cell in referencedCells) // all the cells that were referenced previously but are no longer being referenced. { cell.ValueChanged -= senderCell.OnValueChanged; // unsubsribes from the cell that is no longer being referenced. senderCell.RemoveReferenceToCell(cell); } ExpTree tree = new ExpTree(text); text = tree.Eval().ToString(); } return(text); }
public void Menu() { int flag = 0; string expressionString = "(A1-12-C1)"; //now having error in parentheses string varName; string varValue; double numValue; newExpressionTree = new ExpTree(expressionString); while (flag != 1) //1 causes problems { Console.WriteLine("_________________MENU_________________"); Console.WriteLine("The expression entered is: " + expressionString); /*Console.WriteLine("Would you like to update this expression? Enter y for yes and n for no \n"); * char userInput = Console.ReadKey().KeyChar; //this can cause errors in program testing, just for my own testing purposes * if (userInput == 'y') * { * Console.WriteLine("Please input your new expression with NO whitespaces: \n"); * expressionString = Console.ReadLine(); * * }*/ Console.WriteLine("(1): Update Expression"); Console.WriteLine("(2): Update the value"); Console.WriteLine("(3): Evaluate the tree"); Console.WriteLine("(4): GoodBye"); string userInput = Console.ReadLine().ToString(); Console.WriteLine("You entered option {0}", userInput); switch (userInput) { case "1": Console.WriteLine("Please enter a new expression: "); expressionString = Console.ReadLine(); newExpressionTree = new ExpTree(expressionString); break; case "2": Console.WriteLine("Enter a variable name: "); varName = Console.ReadLine(); Console.WriteLine("Now please enter a value of that variable: "); varValue = Console.ReadLine(); numValue = Convert.ToDouble(varValue); //need to make the value a double Console.WriteLine("Variable Name: {0}\nVariable Value: {1}", varName, numValue); //updated by SHW for readability newExpressionTree.SetVar(varName, numValue); //takes string and double, makes brand new exp tree break; case "3": Console.WriteLine("The result is: {0}", newExpressionTree.Eval()); break; case "4": flag = 1; //exit flag break; } } }
private void findCells(ExpTree tree) { foreach (var item in tree.variables.ToList()) { tree.variables[item.Key] = float.Parse(cellLocation(item.Key).Value); tree.setVar(item.Key, float.Parse(cellLocation(item.Key).Value)); } }
public string Calculator(string newval, Cell hold) { if (newval == string.Empty) { // Clear values and unassign cells if current cell reset foreach (string key in hold.sharevals.Keys) { hold.sharevals[key].PropertyChanged -= hold.Val_PropertyChanged; } hold.sharevals.Clear(); return(""); } else if (newval[0] != '=') { // Clear values and unassign cells if current cell reset foreach (string key in hold.sharevals.Keys) { hold.sharevals[key].PropertyChanged -= hold.Val_PropertyChanged; } hold.sharevals.Clear(); return(newval); } // use getcell to find cell value if set equal to one else { // Added expression tree implementation for '=' condition ExpTree ret = new ExpTree(newval); string grab = ""; string Letters = "[a-zA-Z]+[\\d]*"; string Ops = "[+\\-/*()\\^]"; Regex Val = new Regex(Letters); MatchCollection Matches = Val.Matches(newval); foreach (Match match in Matches) { grab = getCell(match.Value, hold); double set = 0.0; if (double.TryParse(grab, out set)) { ret.setVar(match.Value, set); } else { if (new Regex(Ops).IsMatch(newval) && grab != string.Empty) { return("#REF"); } else { return(grab); } } } return(ret.Evaluate().ToString()); } }
static int Main(string[] Args) { Dictionary <string, double> _dict = new Dictionary <string, double>(); // Set start at values, basically 0+0+0 until A1, B1, and/or C1 declared ExpTree Exp = new ExpTree("A1+B1+C1"); int choice = 0; double result; string choice1 = string.Empty; // Loops indefinitely, ends if selection 4 is chosen while (true) { // Menu portion Console.WriteLine("1) Enter Expression"); Console.WriteLine("2) Set Variable Value"); Console.WriteLine("3) Evaluate Expression"); Console.WriteLine("4) Quit"); Console.Write("Enter Choice: "); choice1 = Console.ReadLine(); Int32.TryParse(choice1, out choice); // Actions for various choices if (choice == 1) { Console.Write("Enter New Expression: "); Exp._Evalstring = Console.ReadLine(); } else if (choice == 2) { // Request Variable name and new value from user Console.Write("Enter Variable Name: "); string replace = Console.ReadLine(); Console.Write("Enter New Value: "); string with = Console.ReadLine(); // Add values to dictionary double.TryParse(with, out result); Exp.setVar(replace, result); // Replace instances of variable with newly established value } else if (choice == 3) { Console.WriteLine(Exp._Evalstring + " = " + Exp.Evaluate()); } else if (choice == 4) { return(0); } // If input isnt 1-4 tell them invalid and ask again else { Console.WriteLine("Invalid Input"); } } }
/************************************************************* * Function: OnPropertyChanged(object sender, PropertyChangedEventArgs e) * Date Created: Feb 8, 2017 * Date Last Modified: Feb 9, 2017 * Description: OnPropertyChanged * Return: void *************************************************************/ public void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Text") { createACell tmpCell = sender as createACell; RemoveDep(tmpCell.Name); if (tmpCell.Text != "" && tmpCell.Text[0] == '=') { ExpTree exp = new ExpTree(tmpCell.Text.Substring(1)); MakeDep(tmpCell.Name, exp.GetAllVariables()); } Eval(sender as Cell); } }
private void DefineVars(ExpTree newTree) { foreach (var name in newTree.varNameList) { var col = name[0] - 'A'; var row = Convert.ToInt32(name.Substring(1)) - 1; var tempCell = GetCell(col, row); try { newTree.SetVar(name, Convert.ToDouble(tempCell.Value)); } catch (FormatException) { } } }
/************************************************************* * Function: setExp(createACell m_Cell, Cell cell) * Date Created: Feb 8, 2017 * Date Last Modified: Feb 9, 2017 * Description: set value to exp * Return: void *************************************************************/ private void setExp(createACell m_Cell, Cell cell) { ExpTree exptree = new ExpTree(m_Cell.Text.Substring(1)); string[] variables = exptree.GetAllVariables(); foreach (string variableName in variables) { Cell variableCell = GetCell(variableName); double value; if (string.IsNullOrEmpty(variableCell.Value)) { exptree.SetVar(variableCell.Name, 0); } else if (!double.TryParse(variableCell.Value, out value)) { exptree.SetVar(variableName, 0); } else { exptree.SetVar(variableName, value); } } //old code from hw4 //string letter = m_Cell.Text.Substring(1); //string number = letter.Substring(1); //string lettersAZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //int col = 0, row = int.Parse(number) - 1; //for (int i = 0; i < 26; i++) //{ // if (lettersAZ[i] == letter[0]) // { // col = i; // break; // } //} //m_Cell.SetValue(GetCell(row, col).Value.ToString()); m_Cell.SetValue(exptree.Eval().ToString()); CellPropertyChanged(cell, new PropertyChangedEventArgs("Value")); }
// sets a cell's value in the ExpTree's variable dictionary private void SetCellVariable(ExpTree userExpTree, string varName) { // get the cell based on the varName Cell relevantCell = GetCell(varName); double value; // check if the cell's value is a double if (double.TryParse(relevantCell.Value, out value)) { // if it's a double, set its variable to that double value userExpTree.SetVar(varName, value); } else { // otherwise set its variable to 0.0 userExpTree.SetVar(varName, 0.0); } }
private void getCellValue(Cell c) { //c = (cell)sender if (c.setText.Length == 0) { c.Value = ""; } else if (!c.setText.StartsWith("=")) //no formula { c.Value = c.setText; } else // formula { if (c.setText.Length > 1) { try { string equation = c.setText.Substring(1); ExpTree xp = new ExpTree(equation); string[] cref = xp.getVariables(); foreach (string name in cref) { double val = getCorrCellVal(name); xp.SetVar(name, val); Cell key = getCorrCell(name); if (!dep.ContainsKey(key)) //add dependency { dep.Add(key, new HashSet <Cell>()); } dep[key].Add(c); } c.Value = xp.Eval().ToString(); } catch { c.Value = "#REF!"; throw; } } } }
static void Main(string[] args) { ExpTree mytree = new ExpTree("22 * 34 * (36 + (37 - 17) * 23)"); //371008 should be the evaluated result string menu = "1"; string words; int numbers; double result; while (menu != "4") { Console.WriteLine("Menu (current expression=\"{0}\")", mytree.rregex); Console.WriteLine(" 1 = Enter a new expression"); Console.WriteLine(" 2 = Set a variable value"); Console.WriteLine(" 3 = Evaluate tree"); Console.WriteLine(" 4 = Quit"); menu = Console.ReadLine(); if (menu == "1") { Console.Write("Enter new expression: "); words = Console.ReadLine(); mytree.rregex = words; mytree = new ExpTree(words); } else if (menu == "2") { Console.Write("Enter variable name: "); words = Console.ReadLine(); Console.Write("Enter variable value: "); numbers = Convert.ToInt32(Console.ReadLine()); mytree.setVar(words, numbers); } else if (menu == "3") { result = mytree.Eval(); Console.WriteLine("{0}", result); } } Console.WriteLine("Done"); }
static void Main(string[] args) { ExpTree mytree = new ExpTree("A1-12-C1"); int menu = 1; string words; int numbers; double result; while (menu != 4) { Console.WriteLine("current expression=\"{0}\")", mytree.rregex); Console.WriteLine(" 1 = Enter a new expression"); Console.WriteLine(" 2 = Set a variable value"); Console.WriteLine(" 3 = Evaluate tree"); Console.WriteLine(" 4 = Quit"); menu = Convert.ToInt32(Console.ReadLine()); if (menu == 1) { Console.Write("Enter new expression: "); words = Console.ReadLine(); mytree.rregex = words; mytree = new ExpTree(words); } else if (menu == 2) { Console.Write("Enter variable name: "); words = Console.ReadLine(); Console.Write("Enter variable value: "); numbers = Convert.ToInt32(Console.ReadLine()); mytree.setVar(words, numbers); } else if (menu == 3) { result = mytree.Eval(); Console.WriteLine("{0}", result); } } Console.WriteLine("Done"); }
// overloaded UpdateCell, takes a cell as the parameter private void UpdateCell(Cell cellToUpdate) { // remove old dependencies RemoveDependencies(cellToUpdate); // first check if the cell is empty // i.e. the user deleted the text from the cell if (string.IsNullOrEmpty(cellToUpdate.Text)) { cellToUpdate.Value = ""; } // if the text doesn't begin with an = else if (cellToUpdate.Text[0] != '=') { double cellValue; // if the cell contains a double if (double.TryParse(cellToUpdate.Text, out cellValue)) { // build the ExpTree to set the cell's variable ExpTree userExpTree = new ExpTree(cellToUpdate.Text); cellValue = userExpTree.Eval(); userExpTree.SetVar(cellToUpdate.Name, cellValue); // update the value to the double cellToUpdate.Value = cellValue.ToString(); } else { // otherwise the value is just set to the text cellToUpdate.Value = cellToUpdate.Text; } } // need to evaluate an expression here else { // parse the text to get the expression string exp = cellToUpdate.Text.Substring(1); // build an ExpTree, eval to add variables ExpTree userExpTree = new ExpTree(exp); userExpTree.Eval(); // get the variable names string[] varNames = userExpTree.GetVarNames(); // loop through each variable name in the array foreach (string variable in varNames) { // get the cell and add its value to the dictionary double value = 0.0; Cell relevantCell = GetCell(variable); // try to parse out the double double.TryParse(relevantCell.Value, out value); // set the variable userExpTree.SetVar(variable, value); } // set the value to the computed value of the ExpTree cellToUpdate.Value = userExpTree.Eval().ToString(); // add the dependencies AddDependencies(cellToUpdate, varNames); } // if there are cells that depend on the one we just updated if (m_dependencies.ContainsKey(cellToUpdate)) { // update all dependent cells UpdateDependencies(cellToUpdate); } // and notify subscribers that the cell property changed // need to pass the sender which is the cell // passing the this reference would pass the spreadsheet CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged")); }
// overloaded UpdateCell, takes a cell as the parameter private void UpdateCell(Cell cellToUpdate) { // remove old dependencies RemoveDependencies(cellToUpdate); // first check if the cell is empty // i.e. the user deleted the text from the cell if (string.IsNullOrEmpty(cellToUpdate.Text)) { cellToUpdate.Value = ""; } // if the text doesn't begin with an = else if (cellToUpdate.Text[0] != '=') { double cellValue; // if the cell contains a double if (double.TryParse(cellToUpdate.Text, out cellValue)) { // build the ExpTree to set the cell's variable ExpTree userExpTree = new ExpTree(cellToUpdate.Text); cellValue = userExpTree.Eval(); userExpTree.SetVar(cellToUpdate.Name, cellValue); // update the value to the double cellToUpdate.Value = cellValue.ToString(); } else { // otherwise the value is just set to the text cellToUpdate.Value = cellToUpdate.Text; } } // need to evaluate an expression here else { // flag to check for errors bool errors = false; // parse the text to get the expression string exp = cellToUpdate.Text.Substring(1); // build an ExpTree, eval to add variables ExpTree userExpTree = new ExpTree(exp); userExpTree.Eval(); // get the variable names string[] varNames = userExpTree.GetVarNames(); // loop through each variable name in the array foreach (string variable in varNames) { // get the cell and add its value to the dictionary double value = 0.0; Cell relevantCell = GetCell(variable); // check for valid cells // CASE ONE: BAD REFERENCE if (relevantCell == null) { // display that the cell has a bad reference and notify subscribers cellToUpdate.Value = "!(bad reference)"; CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged")); // set the error flag to true errors = true; } // CASE TWO: SELF-REFERENCE else if (cellToUpdate.Name == variable) { // display that the cell has a self-reference and notify subscribers cellToUpdate.Value = "!(self reference)"; CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged")); // set the error flag to true errors = true; } // if there's an error, get out of the function if (errors == true) { // if there are cells that depend on the one we just updated if (m_dependencies.ContainsKey(cellToUpdate)) { // update all dependent cells UpdateDependencies(cellToUpdate); } return; } // try to parse out the double double.TryParse(relevantCell.Value, out value); // set the variable userExpTree.SetVar(variable, value); // add the cell to the HashSet to check for circular references this.visitedCells.Add(relevantCell); } // set the value to the computed value of the ExpTree cellToUpdate.Value = userExpTree.Eval().ToString(); // add the dependencies AddDependencies(cellToUpdate, varNames); // check for circular references if (CheckForCircularReferences(cellToUpdate)) { // display that the cell has a circular-reference and notify subscribers cellToUpdate.Value = "!(circular reference)"; CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged")); // set the error flag to true errors = true; } // if there's an error, get out of the function if (errors == true) { return; } } // if there are cells that depend on the one we just updated if (m_dependencies.ContainsKey(cellToUpdate)) { // update all dependent cells UpdateDependencies(cellToUpdate); } // and notify subscribers that the cell property changed // need to pass the sender which is the cell // passing the this reference would pass the spreadsheet CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged")); // clear the visited cells HashSet at a successful cell change this.visitedCells.Clear(); }
private string userInput; // Used for menu interface public ExpTree(string expression) { int operandBegin = 0; // Index of where the first character of the operand exists bool exit = false; // Used for logic with paranthesis and how they are placed onto appropriate stack bool paranthesis = false; // If true, we know that the last paranthesis was placed onto stack and we do not need to create another operand for current operator // Iterate through length of given expression for (int i = 0; i < expression.Length; i++) { char currentChar = expression[i]; // If looking at an operator if (currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/') { // Create an appropriate OpNode OpNode newOp = new OpNode(currentChar.ToString()); // Last thing we looked at was not ')' if (paranthesis == false) { // Create an operand node with last operand and place onto stack Node newNode = determineNode(expression, operandBegin, i); operandStack.Push(newNode); } // We know that there is no 'new' operand to be placed on stack, sub-tree contained in () is already placed onto operand stack else { // Reset the paranthesis flag paranthesis = false; } // Next operand should begin immediately after the operator, note this would be different if urnary operators were included operandBegin = i + 1; // Determine what to do with current and previous operators if (operatorStack.Count > 0) { // Need to peak at top of operand stack, if higher precedence need to push current operand down if (operatorStack.Peek().Precedence < newOp.Precedence) { operatorStack.Push(newOp); } // If lower precedence, need to pop and form node else { OpNode newParent = operatorStack.Pop(); newParent.RightChild = operandStack.Pop(); newParent.LeftChild = operandStack.Pop(); operandStack.Push(newParent); operatorStack.Push(newOp); } } else { // If the operator stack is empty, it is essentially a sentinal like the hint paper was describing operatorStack.Push(newOp); } } else if (currentChar == '(') { // Need to form new tree ExpTree newTree = new ExpTree(expression.Substring(i + 1)); //TEST i = expression.IndexOf(')', i + 1); paranthesis = true; operandStack.Push(newTree.root); } else if (currentChar == ')') { // End new tree, pop back out Node newNode = determineNode(expression, operandBegin, i); operandStack.Push(newNode); root = formTree(operandStack, operatorStack); exit = true; break; } } // Since we are only using binary oprators, the operand stack must be even when expression is completely evaluated if (operandStack.Count > 0 & (operandStack.Count % 2 != 0) & exit == false) { Node newNode = determineNode(expression, operandBegin, expression.Length); operandStack.Push(newNode); } // Provide an entry point for outside world to access root = formTree(operandStack, operatorStack); }
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); } }
public void Cells_PropertyChanged(object sender, PropertyChangedEventArgs e) { SpreadsheetCell spreadsheetCell = sender as SpreadsheetCell; //Sender as a spreadsheet cell switch (e.PropertyName) //switch on the property changed { case ("Text"): //if text has been changed if (spreadsheetCell.Text == string.Empty) { spreadsheetCell.Value = string.Empty; NotifyCellPropertyChanged(spreadsheetCell); //spreadsheetCell.Sendupdate(); } else if (spreadsheetCell.Text[0] == '=') { spreadsheetCell.Value = spreadsheetCell.Text; NotifyCellPropertyChanged(spreadsheetCell); spreadsheetCell.Sendupdate(); } else if (spreadsheetCell.Text[0] != '=' && spreadsheetCell.Value == string.Empty) { spreadsheetCell.Value = spreadsheetCell.Text; NotifyCellPropertyChanged(spreadsheetCell); spreadsheetCell.Sendupdate(); } else if (spreadsheetCell.Text[0] != '=' && spreadsheetCell.Value[0] != '=') { spreadsheetCell.Value = spreadsheetCell.Text; NotifyCellPropertyChanged(spreadsheetCell); spreadsheetCell.Sendupdate(); } break; case ("Value"): try { if (spreadsheetCell.Value != string.Empty) { if (spreadsheetCell.Value[0] == '=') { if (char.IsLetter(spreadsheetCell.Value[1]) && spreadsheetCell.Value.Length <= 4 && spreadsheetCell.Value.Length >= 2) { string varcol = spreadsheetCell.Value[1].ToString(); string varrow = spreadsheetCell.Value.Substring(2); SpreadsheetCell referencedcell = getcellat(varcol, varrow); if (spreadsheetCell.Text != referencedcell.Text) { spreadsheetCell.Text = referencedcell.Text; } referencedcell.Referencesme(spreadsheetCell); } else if (spreadsheetCell.Value.Length >= 2) //starts with = and is within the length of a valid function { ExpTree expTree = new ExpTree(spreadsheetCell.Value.Substring(1)); expTree.Eval(); string varcol; string varrow; double vardata; Dictionary <string, double> vardic = new Dictionary <string, double>(expTree.variables); foreach (string key in vardic.Keys) { varcol = key.Substring(0, 1); varrow = key.Substring(1); SpreadsheetCell referencedcell = getcellat(varcol, varrow); if (referencedcell == spreadsheetCell) { //ToDo-- If self is in the equation vardata = 0; } else { Double.TryParse(referencedcell.Text, out vardata); } referencedcell.Referencesme(spreadsheetCell); expTree.SetVAr(key, vardata); } string eval = expTree.Eval().ToString(); if (spreadsheetCell.Text != eval) { spreadsheetCell.Text = eval; } } } } } catch { spreadsheetCell.Text = "#ERROR"; } break; } }
private void Spreadsheet_PropertyChanged(object sender, PropertyChangedEventArgs e) { //from crandall rmDep((Cell)sender); if (e.PropertyName == "Text") { changedCells.Add((Cell)sender); if (!((Cell)sender).Text.StartsWith("=")) { ((Cell)sender).Value = ((Cell)sender).Text; } else { var expression = ((Cell)sender).Text; //this will get the expression try { var subExp = expression.Substring(1); ExpTree ssExpression = new ExpTree(subExp); DefineVars(ssExpression); ((Cell)sender).Value = ssExpression.Eval().ToString(); if (((Cell)sender).Value == "NaN") { ((Cell)sender).Value = expression; ((Cell)sender).Value = GetCell(expression.Substring(1)).Value; CellPropertyChanged.Invoke(sender, new PropertyChangedEventArgs("Value")); } addDep((Cell)sender, ssExpression.varNameList); } catch { //we are concerned with #REF try { var ssExpression = new ExpTree(((Cell)sender).Text.Substring(1).ToUpper()); ((Cell)sender).Value = "#REF"; CellPropertyChanged.Invoke(sender, new PropertyChangedEventArgs("Value")); addDep((Cell)sender, ssExpression.varNameList); } catch { //need to check if there is an = operator without any following ((Cell)sender).Value = "#REF"; CellPropertyChanged.Invoke(sender, new PropertyChangedEventArgs("Value")); } ((Cell)sender).Value = "#REF"; CellPropertyChanged.Invoke(sender, new PropertyChangedEventArgs("Value")); } } } if (cellDependency.ContainsKey((Cell)sender)) { updateDep((Cell)sender); } CellPropertyChanged.Invoke(sender, new PropertyChangedEventArgs("Value")); }