示例#1
0
        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);
            }
        }