private void updateCellValue(Cell c, string name) { string content = c.getContent(); //get content of cell string preValue = c.getValue(); //get current value of cell c.setPreValue(value); //set previous value of cell to current value int rowIndex = getRowIndexByName(name); //get row index of cell int columnIndex = getColumnIndexByName(name); //get column index of cell List <string> list = new List <string>(); if (content != null && content != "") { expTree = new ExpTree(content.Substring(1)); list = expTree.parseVariables(content.Substring(1)); //get list of variables string n = getCellName(rowIndex, columnIndex); //get name of current cell //addDependencies(n, list); //add to dependencies dictionary string val; foreach (string var in list) { val = getCellByName(var).getValue(); //get numerical value of cell expTree.addToDictionary(var, val); //add variable name and value to expression tree dictionary } if (expTree.getDictionarySize() > 0) //variables exist in the tree { expTree.resetTree(content.Substring(1)); //put variable values in tree } string value = expTree.Eval().ToString(); //get value of expression and convert it to string spreadsheet[rowIndex, columnIndex].setValue(value, true); //set value of cell to new value } else { spreadsheet[rowIndex, columnIndex].setValue("", true); } rowChanged = rowIndex; //save the row number that was changed columnChanged = columnIndex; //save the column number that was changed OnPropertyChanged("content"); //fire property changed event to update UI }
private void CellPropertyChanged(object sender, PropertyChangedEventArgs e) //cell property changed event { int rowIndex = 0, columnIndex = 0; bool found = false; //determine which cell threw the event for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { if (sender.Equals(spreadsheet[i, j])) //check if current cell is the one that sent the event { found = true; rowIndex = i; //save row index of sender columnIndex = j; //save column index of sender break; //break out of loop } } } if ("content" == e.PropertyName) { if (found == true) //only proceed if sender was identified { bool error = false; string content = spreadsheet[rowIndex, columnIndex].getContent(); //get content string if (content != null && content != "") { if (content.StartsWith("=")) //value needs to be updated { List <string> list = new List <string>(); expTree = new ExpTree(content.Substring(1)); list = expTree.parseVariables(content.Substring(1)); //get list of variables if (checkVariablesExist(list)) //only execute following code if all variables exist in the spreadsheet { if (checkSelfReference(list, rowIndex, columnIndex)) //only execute following code if there aren't any self references in the formula { visited.Add(getCell(rowIndex, columnIndex)); //add starting cell to visited hash set string n = getCellName(rowIndex, columnIndex); //get name of current cell removeDependencies(n); //remove old dependencies before adding new ones addDependencies(n, list); //add to dependencies dictionary if (checkCircularReference(getCellName(rowIndex, columnIndex))) //only execute following code if there aren't any circular references in the formula { string val; foreach (string var in list) { val = getCellByName(var).getValue(); //get numerical value of cell expTree.addToDictionary(var, val); //add variable name and value to expression tree dictionary } if (expTree.getDictionarySize() > 0) //variables exist in the tree { expTree.resetTree(content.Substring(1)); //put variable values in tree } string value = expTree.Eval().ToString(); //get value of expression and convert it to string spreadsheet[rowIndex, columnIndex].setValue(value, false); //set value of cell to new value } else //expression in cell contained a circular reference { spreadsheet[rowIndex, columnIndex].setValue("!(circular reference)", false); //set value of cell to error message error = true; //visited.Clear(); //clear visited hash set for the next expression } } else //expression in cell contained a self reference { spreadsheet[rowIndex, columnIndex].setValue("!(self reference)", false); //set value of cell to error message error = true; } } else //expression in cell contained an invalid cell name { spreadsheet[rowIndex, columnIndex].setValue("!(bad reference)", false); //set value of cell to error message error = true; } } else //value is the same as content { string n = getCellName(rowIndex, columnIndex); //get cell name removeDependencies(n); //remove dependencies since cell is now just a constant value and doesn't reference any cells spreadsheet[rowIndex, columnIndex].setValue(content, false); //set value of cell to content of cell } } else { spreadsheet[rowIndex, columnIndex].setValue("", false); } bool success = false; string name = getCellName(rowIndex, columnIndex); //get name of current cell if (error == false) //only update dependencies if there is not an error { //visited.Add(getCellByName(name)); //add starting cell to visited hash set success = updateDependencies(name); //update dependencies of current cell, returns false if there is a circular dependency //if(success == false) //there was a circular dependency in the expression //{ // spreadsheet[rowIndex, columnIndex].setValue("!(circular reference)", false); //set value of cell to error message // setPreValues(getCellByName(name)); //make sure values of dependent cells don't change //} } visited.Clear(); //clear hash set for next expression rowChanged = rowIndex; //save the row number that was changed columnChanged = columnIndex; //save the column number that was changed OnPropertyChanged("content"); //fire PropertyChanged event } } else if ("value" == e.PropertyName) { rowChanged = rowIndex; columnChanged = columnIndex; OnPropertyChanged("content"); //fire PropertyChanged event } else if ("BGColor" == e.PropertyName) { rowChanged = rowIndex; columnChanged = columnIndex; OnPropertyChanged("BGColor"); //fire PropertyChanged event } }