/// <summary>
        /// Will read a text's formula and then subscribe to all the referenced cell's in the formula.
        /// </summary>
        /// <param name="cell">Cell that uses other cells.</param>
        private void SubscribeCellDependency(SpreadsheetCellValue cell)
        {
            if (cell.Text == string.Empty || !cell.Text.StartsWith("=") ||
                cell.Value == "!(bad reference)" || cell.Value == "!(self reference)" ||
                cell.Value == "!(circular reference)")
            {
                return; // Subscribe to nothing if the cell text is empty.
            }

            string cellText = cell.Text.Substring(1, cell.Text.Length - 1);

            string[] words      = cellText.Split('+', '-', '/', '*', '(', ')'); // Splits all the variables and constants.
            int      lengthLoop = words.Length;

            for (int i = 0; i < lengthLoop; i++)
            {
                if (CheckIfLetter(words[i]))
                {
                    string cellCoordinate = words[i].ToUpper(); // Set the A1,B1... to a string variable
                    char   letter         = cellCoordinate[0];
                    int    rowIndex       = Convert.ToInt32(letter) - 65;
                    string numCol         = cellCoordinate.Substring(1, cellCoordinate.Length - 1);
                    int    colIndex       = Convert.ToInt32(numCol) - 1;
                    cell.SubscribeToCell(ref this.cellGrid[colIndex, rowIndex]); // Subscribe to Dependency Changed Event.
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Spreadsheet"/> class.
        /// </summary>
        /// <param name="numRows">Set number of rows in spreadsheet.</param>
        /// <param name="numColumns">Set number of columns in spreadsheet.</param>
        public Spreadsheet(int numRows, int numColumns)
        {
            this.rowCount    = numRows;
            this.columnCount = numColumns;

            this.cellGrid = new SpreadsheetCellValue[numRows, numColumns];

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    SpreadsheetCellValue newCell = SpreadsheetCellValue.CreateCell(i, j);
                    this.cellGrid[i, j] = newCell;
                    this.cellGrid[i, j].PropertyChanged += this.SpreadsheetCellValue_PropertyChanged;
                }
            }
        }
        /// <summary>
        /// This will identify the text of a cell and depending if the text string starts with "=" will update the value of the cell.
        /// If the string starts with "=" this will set the value of the cell to equal another cell's value. Otherwise, the value
        /// will be set equal to the text.
        /// </summary>
        /// <param name="sender.">Spreadsheet.</param>
        /// <param name="e">Cell argument.</param>
        private void SpreadsheetCellValue_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            SpreadsheetCellValue cell = (SpreadsheetCellValue)sender;
            string evalutedText       = cell.Text.ToUpper();
            char   columnCharacter    = Convert.ToChar(cell.ColumnIndex + 65);
            string cellName           = columnCharacter.ToString().ToUpper() + (cell.RowIndex + 1).ToString(); // Converts cell location to a cellName

            try
            {
                this.cellDependencies[cellName] = CreateCellVariableList(evalutedText); // Add cell variables to cellName list.
            }
            catch
            {
            }

            if (e.PropertyName == "Text")
            {
                if (CheckText(evalutedText))
                {
                    if (CheckBadReference(evalutedText))
                    {
                        cell.Value = "!(bad reference)";
                    }
                    else if (CheckSelfReference(evalutedText, cellName))
                    {
                        cell.Value = "!(self reference)";
                    }
                    else if (this.CheckCircleReference(cellName, cellName))
                    {
                        cell.Value = "!(circular reference)";
                    }
                    else
                    {
                        string newValue = this.EvaluateText(evalutedText);
                        this.expressionTree.SetVariable(cellName, Convert.ToDouble(newValue)); // This is assuming that the user inputs the formula without errors and adds the cell value to the dictionary
                        cell.Value = newValue;                                                 // Evaluates the cell text if it starts with "=" and returns the double as a string
                    }
                }
                else
                {
                    string cellValue = cell.Text;

                    double number;
                    if (double.TryParse(cellValue, out number))
                    {
                        this.expressionTree.SetVariable(cellName, number); // If cell value can be parsed to double, set cellName, double
                    }
                    else
                    {
                        this.expressionTree.SetVariable(cellName, 0); // If cell value cannot be parsed to double, set cellName, 0 (default)
                    }

                    cell.Value = cell.Text; // If the string does not start with "=" then the string value will be set to the text of the cell.
                }

                this.SubscribeCellDependency(cell);
                this.PropertyChangedValue(sender, new PropertyChangedEventArgs("Value"));
            }
            else if (e.PropertyName == "BGColor")
            {
                this.PropertyChangedValue(sender, new PropertyChangedEventArgs("BGColor")); // Fire off property changed event for color.
            }
        }
Exemple #4
0
 /// <summary>
 /// This function will allow the cell to subscribe to a referenced cell dependency.
 /// </summary>
 /// <param name="cell">Refereneced cell that this.cell will subscribe to.</param>
 public void SubscribeToCell(ref SpreadsheetCellValue cell)
 {
     cell.DependencyChanged += this.SpreadsheetCellValue_DependencyChanged;
 }