//cell Property change handler
        private void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            AbstractCell cell = (AbstractCell)sender;

            switch (e.PropertyName)
            {
            case "Text":
                cell.EvaluatedValue = changedCellStringContents(cell);
                break;

            case "Value":
                //TODO:
                break;

            default:
                break;
            }
            NotifyCellPropertyChanged(cell);
        }
        //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]);
            }
        }
 //Event used to alert UI-layer code to update the content of a cell
 public void NotifyCellPropertyChanged(AbstractCell cell)
 {
     CellPropertyChanged?.Invoke(cell, new PropertyChangedEventArgs("Cell"));
 }