//Invoke the data changed event protected virtual void OnDataChanged(DataChangedEventArgs e) { if (DataChanged != null) DataChanged(this, e); }
void ReactionViewer_DataChanged(object sender, DataChangedEventArgs e) { Console.WriteLine("Updating control since the data changed"); }
void CompoundDataChanged(object sender, DataChangedEventArgs e) { //When we are changing things programatically we don't want to hear about those changes if (supressCompoundEvents) return; Console.WriteLine("Synthesis sees that something has changed in a reactant "+ (COMPOUND_FIELDS)e.field); Compound _sender = sender as Compound; if (_sender == null) return; //If the field is a change in type then we need to move this compound to a differnt list if (e.field == (int)COMPOUND_FIELDS.Type) { if (reactants.Contains(_sender)) reactants.Remove(_sender); if (reagents.Contains(_sender)) reagents.Remove(_sender); if (products.Contains(_sender)) products.Remove(_sender); if (_sender.Type == COMPOUND_TYPES.Reactant) { reactants.Add(_sender); } else if (_sender.Type == COMPOUND_TYPES.Reagent) { reagents.Add(_sender); } else { products.Add(_sender); } OnSynthesisChanged(EventArgs.Empty); //let other components know that the synthesis has changed return; } //When we have mols changed and a limiting reactant (the sender) we want to balance everything with respect to the limiting reactant //When mols are changed and there is a limiting reactant, but it is NOT the sender we want to change this compounds equivalency with respect to the limiting reactant if (hasLimitingReactant && e.field == (int)COMPOUND_FIELDS.Mols) { if (_sender.IsLimiting) { //If this is the limiting reactant we recalculate the other reactants with respect to this one based on their equivalency //but first we need to calculate new mass and volume for the sender supressCompoundEvents = true; _sender.Mass = new Unit(_sender.Mols.BaseValue * _sender.MolWeight, "g", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Liquid) _sender.Volume = new Unit(_sender.Mass.BaseValue / (_sender.Density * Math.Pow(10, 3)), "l", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Solution) _sender.Volume = new Unit(_sender.Mols.BaseValue / _sender.SolutionConc.BaseValue, "l", (int)UNIT_POWERS.none); BalanceFromEquivalency(_sender); supressCompoundEvents = false; } else { //if the sender is not the limiting reactant we calculate a new mass and volume, and change the equivalency //m = n * M supressCompoundEvents = true; _sender.Mass = new Unit(_sender.Mols.BaseValue * _sender.MolWeight, "g", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Liquid) _sender.Volume = new Unit(_sender.Mass.BaseValue / (_sender.Density * Math.Pow(10, 3)), "l", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Solution) _sender.Volume = new Unit(_sender.Mols.BaseValue / _sender.SolutionConc.BaseValue, "l", (int)UNIT_POWERS.none); _sender.Equivalency = _sender.Mols.BaseValue / LimitingReactant.Mols.BaseValue; OnSynthesisChanged(EventArgs.Empty); supressCompoundEvents = false; } return; } //When we have mass changed and a limiting reactant (the sender) we want to balance everything with respect to the limiting reactant //When mass are changed and there is a limiting reactant, but it is NOT the sender we want to change this compounds equivalency with respect to the limiting reactant if (hasLimitingReactant && e.field == (int)COMPOUND_FIELDS.Mass) { if (_sender.IsLimiting) { //If this is the limiting reactant we recalculate the other reactants with respect to this one based on their equivalency //but first we need our new mols value supressCompoundEvents = true; _sender.Mols = new Unit(_sender.Mass.BaseValue / _sender.MolWeight, "mol", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Liquid) _sender.Volume = new Unit(_sender.Mass.BaseValue / (_sender.Density * Math.Pow(10, 3)), "l", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Solution) _sender.Volume = new Unit(_sender.Mols.BaseValue / _sender.SolutionConc.BaseValue, "l", (int)UNIT_POWERS.none); BalanceFromEquivalency(_sender); supressCompoundEvents = false; } else { //if the sender is not the limiting reactant we calculate a new mols and volume, and change the equivalency //m = n * M supressCompoundEvents = true; _sender.Mols = new Unit(_sender.Mass.BaseValue / _sender.MolWeight, "mol", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Liquid) _sender.Volume = new Unit(_sender.Mass.BaseValue / (_sender.Density * Math.Pow(10, 3)), "l", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Solution) _sender.Volume = new Unit(_sender.Mols.BaseValue / _sender.SolutionConc.BaseValue, "l", (int)UNIT_POWERS.none); _sender.Equivalency = _sender.Mols.BaseValue / LimitingReactant.Mols.BaseValue; OnSynthesisChanged(EventArgs.Empty); supressCompoundEvents = false; } } //When we have volume changed and a limiting reactant (the sender) we want to balance everything with respect to the limiting reactant //When volumes are changed and there is a limiting reactant, but it is NOT the sender we want to change this compounds equivalency with respect to the limiting reactant if (hasLimitingReactant && e.field == (int)COMPOUND_FIELDS.Volume) { if (_sender.IsLimiting) { //If this is the limiting reactant we recalculate the other reactants with respect to this one based on their equivalency //but first we need our new mols value supressCompoundEvents = true; if (_sender.State == PHASE_STATE.Solution) _sender.Mols = new Unit(_sender.SolutionConc.BaseValue * _sender.Volume.BaseValue, "mol", (int)UNIT_POWERS.none); else if (_sender.State == PHASE_STATE.Liquid) _sender.Mols = new Unit(_sender.Density * Math.Pow(10, 3) * _sender.Volume.BaseValue / _sender.MolWeight, "mol", (int)UNIT_POWERS.none); else return; _sender.Mass = new Unit(_sender.Mols.BaseValue * _sender.MolWeight, "g", (int)UNIT_POWERS.none); BalanceFromEquivalency(_sender); supressCompoundEvents = false; } else { //if the sender is not the limiting reactant we calculate a new mols and mass, and change the equivalency //m = n * M supressCompoundEvents = true; if (_sender.State == PHASE_STATE.Solution) _sender.Mols = new Unit(_sender.SolutionConc.BaseValue * _sender.Volume.BaseValue, "mol", (int)UNIT_POWERS.none); else if (_sender.State == PHASE_STATE.Liquid) _sender.Mols = new Unit(_sender.Density * Math.Pow(10, 3) * _sender.Volume.BaseValue / _sender.MolWeight, "mol", (int)UNIT_POWERS.none); else return; _sender.Mass = new Unit(_sender.Mols.BaseValue * _sender.MolWeight, "g", (int)UNIT_POWERS.none); _sender.Equivalency = _sender.Mols.BaseValue / LimitingReactant.Mols.BaseValue; OnSynthesisChanged(EventArgs.Empty); supressCompoundEvents = false; } } //Changing density we change the volume value if (e.field == (int)COMPOUND_FIELDS.Density) { supressCompoundEvents = true; _sender.Volume = new Unit(_sender.Mols.BaseValue * _sender.MolWeight / (_sender.Density * Math.Pow(10, 3)), "l", (int)UNIT_POWERS.none); //density is g/ml so our result is in ml OnSynthesisChanged(EventArgs.Empty); supressCompoundEvents = false; } if (e.field == (int)COMPOUND_FIELDS.Solvent) { supressCompoundEvents = true; _sender.Volume = new Unit(_sender.Mols.BaseValue / _sender.SolutionConc.BaseValue, "l", (int)UNIT_POWERS.none); OnSynthesisChanged(EventArgs.Empty); supressCompoundEvents = false; } //When the user changes the equivalency then we get new values for mols, mass and volume //if the sender is the limiting reactant then equivalency changes have no meaning, and we need a limiting reactant if we are to balance anything if (e.field == (int)COMPOUND_FIELDS.Equivalency && LimitingReactant != null && _sender != LimitingReactant) { _sender.Mols = new Unit(LimitingReactant.Mols.BaseValue * _sender.Equivalency, "mol", (int)UNIT_POWERS.none); _sender.Mass = new Unit(_sender.Mols.BaseValue * _sender.MolWeight, "g", (int)UNIT_POWERS.none); if (_sender.State == PHASE_STATE.Liquid) _sender.Volume = new Unit(_sender.Mass.BaseValue / _sender.Density, "l", (int)UNIT_POWERS.none); } }