public PIDTuningTool(Shared.Flowsheet fs, DynamicsIntegratorControl intcontrol) : base() { Flowsheet = fs; intc = intcontrol; Padding = new Eto.Drawing.Padding(5); Spacing = new Size(5, 5); Padding = new Eto.Drawing.Padding(5); Spacing = new Size(10, 10); var leftcontainer = new DynamicLayout { Width = 300 }; leftcontainer.CreateAndAddLabelRow("Schedule"); var schlist = Flowsheet.DynamicsManager.ScheduleList.Values.ToList(); var cbSchedule = leftcontainer.CreateAndAddDropDownRow("Schedule", schlist.Select((x) => x.Description).ToList(), 0, (dd, e) => schedule = schlist[dd.SelectedIndex]); leftcontainer.CreateAndAddLabelRow("Controllers"); leftcontainer.CreateAndAddDescriptionRow("Select the PID Controllers to tune."); var listb = new CheckBoxList() { Height = 200 }; foreach (var obj in Flowsheet.SimulationObjects.Values.Where((x) => x.ObjectClass == Interfaces.Enums.SimulationObjectClass.Controllers)) { listb.Items.Add(obj.GraphicObject.Tag, obj.Name); } leftcontainer.CreateAndAddControlRow(listb); leftcontainer.CreateAndAddNumericEditorRow("Maximum Iterations", iterations, 5, 100, 0, (ns, e) => { iterations = (int)ns.Value; }); var btnRun = leftcontainer.CreateAndAddButtonRow("Begin Tuning", null, null); var btnCancel = leftcontainer.CreateAndAddButtonRow("Cancel", null, (btn, e) => Abort = true); txtResults = new TextArea { ReadOnly = true, Wrap = true }; Rows.Add(new TableRow(leftcontainer, new Scrollable { Content = txtResults })); btnRun.Click += (s, e) => { Flowsheet.RunCodeOnUIThread(() => { txtResults.Text = ""; if (!Flowsheet.DynamicMode) { txtResults.Text += "Error: Dynamic Mode is not activated. Activate Dynamic Mode and try again."; return; } intc.cbsc.SelectedIndex = cbSchedule.SelectedIndex; var schedule = Flowsheet.DynamicsManager.ScheduleList[Flowsheet.DynamicsManager.CurrentSchedule]; List <OptSimplexBoundVariable> vars = new List <OptSimplexBoundVariable>(); List <PIDController> controllers = new List <PIDController>(); foreach (var item in listb.SelectedKeys) { var controller = (PIDController)Flowsheet.SimulationObjects[item]; controllers.Add(controller); vars.Add(new OptSimplexBoundVariable(controller.Kp, 0.0, controller.Kp * 10)); vars.Add(new OptSimplexBoundVariable(controller.Ki, 0.0, 100.0)); vars.Add(new OptSimplexBoundVariable(controller.Kd, 0.0, 100.0)); } btnRun.Enabled = false; btnCancel.Enabled = true; Simplex simplex = new Simplex(); simplex.MaxFunEvaluations = iterations; Abort = false; int counter = 1; if (schedule.InitialFlowsheetStateID == "" | schedule.UseCurrentStateAsInitial) { txtResults.Text += "The selected schedule must have a valid initial state to start from."; btnRun.Enabled = true; btnCancel.Enabled = false; return; } var result = simplex.ComputeMin(x => { if (Abort) { return(0.0); } Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Beginning Iteration #{0}...\n", counter)); }); intc.RestoreState(schedule.InitialFlowsheetStateID); var i = 0; foreach (var controller in controllers) { controller.Kp = x[i]; controller.Ki = x[i + 1]; controller.Kd = x[i + 2]; Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Controller: {0} - Kp = {1}, Ki = {2}, Kd = {3}\n", controller.GraphicObject.Tag, controller.Kp, controller.Ki, controller.Kd)); }); i += 3; } intc.RunIntegrator(false, true); var totalerror = controllers.Select(c => c.CumulativeError).ToArray().AbsSumY(); Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Total Error: {0}\n", totalerror)); txtResults.CaretIndex = txtResults.Text.Length - 1; }); Application.Instance.RunIteration(); counter += 1; return(totalerror); }, vars.ToArray()); if (Abort) { txtResults.Text += (string.Format("Tuning aborted by the user. Results:\n")); } else { txtResults.Text += (string.Format("Tuning finished successfully. Results:\n")); } var j = 0; foreach (var controller in controllers) { controller.Kp = result[j]; controller.Ki = result[j + 1]; controller.Kd = result[j + 2]; txtResults.Text += (string.Format("Controller: {0} - Kp = {1}, Ki = {2}, Kd = {3}\n", controller.GraphicObject.Tag, controller.Kp, controller.Ki, controller.Kd)); j += 3; } btnRun.Enabled = true; btnCancel.Enabled = false; Flowsheet.UpdateInterface(); }); }; }
void Initialize() { container.CreateAndAddLabelRow("Reaction ID"); container.CreateAndAddStringEditorRow2("Name", "", rx.Name, (sender, e) => { rx.Name = sender.Text; }); container.CreateAndAddLabelRow("Compounds and Stoichiometry (Include / Name / Stoich. Coeff. / Direct Order Exponent / Reverse Order Exponent)"); var compcontainer = new DynamicLayout(); compcontainer.BackgroundColor = Colors.White; Double val; foreach (ICompoundConstantProperties comp in flowsheet.SelectedCompounds.Values) { var chk = new CheckBox() { Text = comp.Name, Checked = (rx.Components.ContainsKey(comp.Name) ? true : false) }; chk.CheckedChanged += (sender, e) => { if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, 0)); } else { rx.Components.Remove(comp.Name); } UpdateEquation(); }; var sc = new TextBox() { Width = 30, Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].StoichCoeff.ToString() : 0.0f.ToString()) }; sc.TextChanged += (sender, e) => { if (Double.TryParse(sc.Text.ToString(), out val)) { sc.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, Double.Parse(sc.Text), false, 0, 0)); } else { rx.Components[comp.Name].StoichCoeff = double.Parse(sc.Text); } UpdateEquation(); } else { sc.TextColor = Colors.Red; } }; var txtdo = new TextBox() { Width = 30, Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].DirectOrder.ToString() : 0.0f.ToString()) }; txtdo.TextChanged += (sender, e) => { if (Double.TryParse(txtdo.Text.ToString(), out val)) { txtdo.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, Double.Parse(txtdo.Text), 0)); } else { rx.Components[comp.Name].DirectOrder = double.Parse(txtdo.Text); } UpdateEquation(); } else { txtdo.TextColor = Colors.Red; } }; var txtro = new TextBox() { Width = 30, Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].ReverseOrder.ToString() : 0.0f.ToString()) }; txtro.TextChanged += (sender, e) => { if (Double.TryParse(txtro.Text.ToString(), out val)) { txtro.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, Double.Parse(txtro.Text))); } else { rx.Components[comp.Name].ReverseOrder = double.Parse(txtro.Text); } UpdateEquation(); } else { txtro.TextColor = Colors.Red; } }; compcontainer.Add(new TableRow(chk, null, sc, txtdo, txtro)); } container.CreateAndAddControlRow(compcontainer); container.CreateAndAddEmptySpace(); var comps = flowsheet.SelectedCompounds.Values.Select((x) => x.Name).ToList(); comps.Insert(0, ""); container.CreateAndAddLabelRow("Base Compound"); var basecompselector = container.CreateAndAddDropDownRow("Base Compound", comps, 0, null); var basecomp = rx.Components.Values.Where((x) => x.IsBaseReactant).FirstOrDefault(); if (basecomp != null) { basecompselector.SelectedIndex = comps.IndexOf(basecomp.CompName); } else { basecompselector.SelectedIndex = 0; } basecompselector.SelectedIndexChanged += (sender, e) => { if (rx.Components.ContainsKey(comps[basecompselector.SelectedIndex])) { foreach (var rxc in rx.Components.Values) { rxc.IsBaseReactant = false; } rx.Components[comps[basecompselector.SelectedIndex]].IsBaseReactant = true; rx.BaseReactant = comps[basecompselector.SelectedIndex]; } }; container.CreateAndAddLabelRow("Reaction Balance"); txtEquation = container.CreateAndAddLabelRow2(""); container.CreateAndAddLabelRow("Reaction Phase"); var rxphaseselector = container.CreateAndAddDropDownRow("Reaction Phase", Shared.StringArrays.reactionphase().ToList(), 0, null); switch (rx.ReactionPhase) { case Interfaces.Enums.PhaseName.Vapor: rxphaseselector.SelectedIndex = (0); break; case Interfaces.Enums.PhaseName.Liquid: rxphaseselector.SelectedIndex = (1); break; case Interfaces.Enums.PhaseName.Mixture: rxphaseselector.SelectedIndex = (2); break; } rxphaseselector.SelectedIndexChanged += (sender, e) => { switch (rxphaseselector.SelectedIndex) { case 0: rx.ReactionPhase = Interfaces.Enums.PhaseName.Vapor; break; case 1: rx.ReactionPhase = Interfaces.Enums.PhaseName.Liquid; break; case 2: rx.ReactionPhase = Interfaces.Enums.PhaseName.Mixture; break; } }; container.CreateAndAddLabelRow("Reaction Basis"); var rxbasisselector = container.CreateAndAddDropDownRow("Reaction Basis", Shared.StringArrays.reactionbasis().ToList(), 0, null); switch (rx.ReactionBasis) { case Interfaces.Enums.ReactionBasis.Activity: rxphaseselector.SelectedIndex = (0); break; case Interfaces.Enums.ReactionBasis.Fugacity: rxphaseselector.SelectedIndex = (1); break; case Interfaces.Enums.ReactionBasis.MassConc: rxphaseselector.SelectedIndex = (2); break; case Interfaces.Enums.ReactionBasis.MassFrac: rxphaseselector.SelectedIndex = (3); break; case Interfaces.Enums.ReactionBasis.MolarConc: rxphaseselector.SelectedIndex = (4); break; case Interfaces.Enums.ReactionBasis.MolarFrac: rxphaseselector.SelectedIndex = (5); break; case Interfaces.Enums.ReactionBasis.PartialPress: rxphaseselector.SelectedIndex = (6); break; } rxbasisselector.SelectedIndexChanged += (sender, e) => { switch (rxbasisselector.SelectedIndex) { case 0: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Activity; break; case 1: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Fugacity; break; case 2: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassConc; break; case 3: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassFrac; break; case 4: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarConc; break; case 5: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarFrac; break; case 6: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.PartialPress; break; } }; container.CreateAndAddLabelRow("Kinetic Parameters"); var nf = flowsheet.FlowsheetOptions.NumberFormat; var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; container.CreateAndAddTextBoxRow(nf, "Minimum Temperature", rx.Tmin.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmin = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); container.CreateAndAddTextBoxRow(nf, "Maximum Temperature", rx.Tmax.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmax = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); container.CreateAndAddLabelRow2("Direct and Reverse Reactions Velocity Constants (k = A*exp(-E/RT), E in J/mol and T in K)"); container.CreateAndAddStringEditorRow2("Direct Reaction A", "", rx.A_Forward.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.A_Forward = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); container.CreateAndAddStringEditorRow2("Direct Reaction E", "", rx.E_Forward.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.E_Forward = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); container.CreateAndAddStringEditorRow2("Reverse Reaction A", "", rx.A_Reverse.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.A_Reverse = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); container.CreateAndAddStringEditorRow2("Reverse Reaction E", "", rx.E_Reverse.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.E_Reverse = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); container.CreateAndAddLabelRow("Units"); var us = new DWSIM.SharedClasses.SystemsOfUnits.Units(); var units = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.molar_conc); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.mass_conc)); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.pressure)); units.Insert(0, ""); container.CreateAndAddDropDownRow("Basis Units (Base Compound)", units, units.IndexOf(rx.ConcUnit), (sender, e) => rx.ConcUnit = sender.SelectedValue.ToString()); var units2 = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.reac_rate); units2.Insert(0, ""); container.CreateAndAddDropDownRow("Velocity Units", units2, units2.IndexOf(rx.VelUnit), (sender, e) => rx.VelUnit = sender.SelectedValue.ToString()); UpdateEquation(); }
void Initialize() { container.CreateAndAddLabelRow("Reaction ID"); container.CreateAndAddStringEditorRow2("Name", "", rx.Name, (sender, e) => { rx.Name = sender.Text; }); DynamicLayout p1, p2; TableLayout t1; p1 = UI.Shared.Common.GetDefaultContainer(); p2 = UI.Shared.Common.GetDefaultContainer(); p1.Width = 420; t1 = new TableLayout(); t1.Rows.Add(new TableRow(p1, p2)); p1.CreateAndAddLabelRow("Compounds and Stoichiometry (Include / Name / Heat of Formation (kJ/kg) / Stoich. Coeff. / Direct Order Exponent / Reverse Order Exponent)"); var compcontainer = new DynamicLayout(); Double val; foreach (ICompoundConstantProperties comp in flowsheet.SelectedCompounds.Values) { var chk = new CheckBox() { Text = comp.Name, Checked = (rx.Components.ContainsKey(comp.Name) ? true : false) }; chk.CheckedChanged += (sender, e) => { if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, 0)); } else { rx.Components.Remove(comp.Name); } UpdateEquation(); }; var sc = new TextBox() { Width = (int)(sf * 30), Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].StoichCoeff.ToString() : 0.0f.ToString()) }; sc.TextChanged += (sender, e) => { if (Double.TryParse(sc.Text.ToString(), out val)) { sc.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, Double.Parse(sc.Text), false, 0, 0)); } else { rx.Components[comp.Name].StoichCoeff = double.Parse(sc.Text); } UpdateEquation(); } else { sc.TextColor = Colors.Red; } }; var txtdo = new TextBox() { Width = (int)(sf * 30), Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].DirectOrder.ToString() : 0.0f.ToString()) }; txtdo.TextChanged += (sender, e) => { if (Double.TryParse(txtdo.Text.ToString(), out val)) { txtdo.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, Double.Parse(txtdo.Text), 0)); } else { rx.Components[comp.Name].DirectOrder = double.Parse(txtdo.Text); } UpdateEquation(); } else { txtdo.TextColor = Colors.Red; } }; var txtro = new TextBox() { Width = (int)(sf * 30), Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].ReverseOrder.ToString() : 0.0f.ToString()) }; txtro.TextChanged += (sender, e) => { if (Double.TryParse(txtro.Text.ToString(), out val)) { txtro.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, Double.Parse(txtro.Text))); } else { rx.Components[comp.Name].ReverseOrder = double.Parse(txtro.Text); } UpdateEquation(); } else { txtro.TextColor = Colors.Red; } }; var hf = new TextBox() { Enabled = false, Width = (int)(sf * 100), Text = comp.IG_Enthalpy_of_Formation_25C.ToString("N2") }; compcontainer.Add(new TableRow(chk, null, hf, sc, txtdo, txtro)); } p1.CreateAndAddControlRow(compcontainer); p1.CreateAndAddEmptySpace(); var comps = flowsheet.SelectedCompounds.Values.Select((x) => x.Name).ToList(); comps.Insert(0, ""); p1.CreateAndAddLabelRow("Base Compound"); var basecompselector = p1.CreateAndAddDropDownRow("Base Compound", comps, 0, null); var basecomp = rx.Components.Values.Where((x) => x.IsBaseReactant).FirstOrDefault(); if (basecomp != null) { basecompselector.SelectedIndex = comps.IndexOf(basecomp.CompName); } else { basecompselector.SelectedIndex = 0; } basecompselector.SelectedIndexChanged += (sender, e) => { if (rx.Components.ContainsKey(comps[basecompselector.SelectedIndex])) { foreach (var rxc in rx.Components.Values) { rxc.IsBaseReactant = false; } rx.Components[comps[basecompselector.SelectedIndex]].IsBaseReactant = true; rx.BaseReactant = comps[basecompselector.SelectedIndex]; UpdateEquation(); } }; p1.CreateAndAddLabelRow("Reaction Balance"); txtEquation = p1.CreateAndAddLabelRow2(""); p1.CreateAndAddLabelRow("Reaction Phase"); var rxphaseselector = p1.CreateAndAddDropDownRow("Reaction Phase", Shared.StringArrays.reactionphase().ToList(), 0, null); switch (rx.ReactionPhase) { case Interfaces.Enums.PhaseName.Mixture: rxphaseselector.SelectedIndex = (0); break; case Interfaces.Enums.PhaseName.Vapor: rxphaseselector.SelectedIndex = (1); break; case Interfaces.Enums.PhaseName.Liquid: rxphaseselector.SelectedIndex = (2); break; } rxphaseselector.SelectedIndexChanged += (sender, e) => { switch (rxphaseselector.SelectedIndex) { case 0: rx.ReactionPhase = Interfaces.Enums.PhaseName.Mixture; break; case 1: rx.ReactionPhase = Interfaces.Enums.PhaseName.Vapor; break; case 2: rx.ReactionPhase = Interfaces.Enums.PhaseName.Liquid; break; } }; p1.CreateAndAddLabelRow("Reaction Basis"); var rxbasisselector = p1.CreateAndAddDropDownRow("Reaction Basis", Shared.StringArrays.reactionbasis().ToList(), 0, null); switch (rx.ReactionBasis) { case Interfaces.Enums.ReactionBasis.Activity: rxbasisselector.SelectedIndex = (0); break; case Interfaces.Enums.ReactionBasis.Fugacity: rxbasisselector.SelectedIndex = (1); break; case Interfaces.Enums.ReactionBasis.MassConc: rxbasisselector.SelectedIndex = (2); break; case Interfaces.Enums.ReactionBasis.MassFrac: rxbasisselector.SelectedIndex = (3); break; case Interfaces.Enums.ReactionBasis.MolarConc: rxbasisselector.SelectedIndex = (4); break; case Interfaces.Enums.ReactionBasis.MolarFrac: rxbasisselector.SelectedIndex = (5); break; case Interfaces.Enums.ReactionBasis.PartialPress: rxbasisselector.SelectedIndex = (6); break; } rxbasisselector.SelectedIndexChanged += (sender, e) => { switch (rxbasisselector.SelectedIndex) { case 0: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Activity; break; case 1: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Fugacity; break; case 2: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassConc; break; case 3: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassFrac; break; case 4: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarConc; break; case 5: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarFrac; break; case 6: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.PartialPress; break; } }; p1.CreateAndAddLabelRow("Temperature Limits"); var nf = flowsheet.FlowsheetOptions.NumberFormat; var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; p1.CreateAndAddTextBoxRow(nf, "Minimum Temperature (" + su.temperature + ")", rx.Tmin.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmin = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); p1.CreateAndAddTextBoxRow(nf, "Maximum Temperature (" + su.temperature + ")", rx.Tmax.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmax = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); p2.CreateAndAddLabelRow("Reaction Kinetics"); p2.CreateAndAddCheckBoxRow("Advanced Kinetics", rx.ReactionKinetics == Interfaces.Enums.ReactionKinetics.PythonScript, (chk, e) => { if (chk.Checked.GetValueOrDefault()) { rx.ReactionKinetics = Interfaces.Enums.ReactionKinetics.PythonScript; } else { rx.ReactionKinetics = Interfaces.Enums.ReactionKinetics.Expression; } }); var scripts = new List <string>(); scripts.Add(""); scripts.AddRange(flowsheet.Scripts.Values.Select(x => x.Title).ToArray()); p2.CreateAndAddDropDownRow("Python Script (for Advanced Kinetics)", scripts, scripts.Contains(rx.ScriptTitle) ? scripts.IndexOf(rx.ScriptTitle) : 0, (cb, e) => rx.ScriptTitle = cb.SelectedValue.ToString()); p2.CreateAndAddDescriptionRow("Create a Python Script using the Script Manager which returns the reaction rate 'r' in the currently selected units. " + "You can get the compound amounts through the R1, R2, ..., Rn, P1, P2, ..., Pn and N1, N2, ... Nn variables or use the 'Amounts' dictionary to get the amount by the compound's name. " + "You can also use the current temperature 'T' in Kelvin and pressure 'P' in Pa."); p2.CreateAndAddLabelRow("Velocity Constant for Forward Reactions"); p2.CreateAndAddDropDownRow("Equation Type for Forward Reactions", new List <string>() { "Arrhenius (k = A*exp(-E/RT))", "User-Defined Expression" }, (int)rx.ReactionKinFwdType, (sender, e) => { switch (sender.SelectedIndex) { case 0: rx.ReactionKinFwdType = Interfaces.Enums.ReactionKineticType.Arrhenius; break; case 1: rx.ReactionKinFwdType = Interfaces.Enums.ReactionKineticType.UserDefined; break; } }); p2.CreateAndAddStringEditorRow2("A", "", rx.A_Forward.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.A_Forward = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); p2.CreateAndAddStringEditorRow2("E", "", rx.E_Forward.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.E_Forward = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); p2.CreateAndAddStringEditorRow2("User Expression - f(T), T in K", "", rx.ReactionKinFwdExpression, (sender, e) => { rx.ReactionKinFwdExpression = sender.Text; }); p2.CreateAndAddLabelRow("Velocity Constant for Reverse Reactions"); p2.CreateAndAddDropDownRow("Equation Type for Reverse Reactions", new List <string>() { "Arrhenius (k = A*exp(-E/RT))", "User-Defined Expression" }, (int)rx.ReactionKinRevType, (sender, e) => { switch (sender.SelectedIndex) { case 0: rx.ReactionKinRevType = Interfaces.Enums.ReactionKineticType.Arrhenius; break; case 1: rx.ReactionKinRevType = Interfaces.Enums.ReactionKineticType.UserDefined; break; } }); p2.CreateAndAddStringEditorRow2("A", "", rx.A_Reverse.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.A_Reverse = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); p2.CreateAndAddStringEditorRow2("E (J/mol)", "", rx.E_Reverse.ToString(), (sender, e) => { if (Double.TryParse(sender.Text.ToString(), out val)) { sender.TextColor = SystemColors.ControlText; rx.E_Reverse = double.Parse(sender.Text); } else { sender.TextColor = Colors.Red; } }); p2.CreateAndAddStringEditorRow2("User Expression - f(T), T in K", "", rx.ReactionKinRevExpression, (sender, e) => { rx.ReactionKinRevExpression = sender.Text; }); p2.CreateAndAddLabelRow("Units"); var us = new DWSIM.SharedClasses.SystemsOfUnits.Units(); var units = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.molar_conc); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.mass_conc)); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.pressure)); units.Insert(0, ""); p2.CreateAndAddDropDownRow("Basis Units (Base Compound)", units, units.IndexOf(rx.ConcUnit), (sender, e) => rx.ConcUnit = sender.SelectedValue.ToString()); var units2 = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.reac_rate); units2.Insert(0, ""); p2.CreateAndAddDropDownRow("Velocity Units", units2, units2.IndexOf(rx.VelUnit), (sender, e) => rx.VelUnit = sender.SelectedValue.ToString()); var units3 = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.molar_enthalpy); units3.Insert(0, ""); p2.CreateAndAddDropDownRow("E (Forward)", units3, units3.IndexOf(rx.E_Forward_Unit), (sender, e) => rx.E_Forward_Unit = sender.SelectedValue.ToString()); p2.CreateAndAddDropDownRow("E (Reverse)", units3, units3.IndexOf(rx.E_Reverse_Unit), (sender, e) => rx.E_Reverse_Unit = sender.SelectedValue.ToString()); UpdateEquation(); container.Add(t1); }
void Initialize() { container.CreateAndAddLabelRow("Reaction ID"); container.CreateAndAddStringEditorRow2("Name", "", rx.Name, (sender, e) => { rx.Name = sender.Text; }); container.CreateAndAddLabelRow("Compounds and Stoichiometry (Include / Name / Stoich. Coeff.)"); var compcontainer = new DynamicLayout(); compcontainer.BackgroundColor = Colors.White; Double val; foreach (ICompoundConstantProperties comp in flowsheet.SelectedCompounds.Values) { var chk = new CheckBox() { Text = comp.Name, Checked = (rx.Components.ContainsKey(comp.Name) ? true : false) }; chk.CheckedChanged += (sender, e) => { if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, 0)); } else { rx.Components.Remove(comp.Name); } UpdateEquation(); }; var sc = new TextBox() { Width = (int)(sf * 50), Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].StoichCoeff.ToString() : 0.0f.ToString()) }; sc.TextChanged += (sender, e) => { if (Double.TryParse(sc.Text.ToString(), out val)) { sc.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, Double.Parse(sc.Text), false, 0, 0)); } else { rx.Components[comp.Name].StoichCoeff = double.Parse(sc.Text); } UpdateEquation(); } else { sc.TextColor = Colors.Red; } }; compcontainer.Add(new TableRow(chk, null, sc)); } container.CreateAndAddControlRow(compcontainer); container.CreateAndAddEmptySpace(); var comps = flowsheet.SelectedCompounds.Values.Select((x) => x.Name).ToList(); comps.Insert(0, ""); container.CreateAndAddLabelRow("Base Compound"); var basecompselector = container.CreateAndAddDropDownRow("Base Compound", comps, 0, null); var basecomp = rx.Components.Values.Where((x) => x.IsBaseReactant).FirstOrDefault(); if (basecomp != null) { basecompselector.SelectedIndex = comps.IndexOf(basecomp.CompName); } else { basecompselector.SelectedIndex = 0; } basecompselector.SelectedIndexChanged += (sender, e) => { if (rx.Components.ContainsKey(comps[basecompselector.SelectedIndex])) { foreach (var rxc in rx.Components.Values) { rxc.IsBaseReactant = false; } rx.Components[comps[basecompselector.SelectedIndex]].IsBaseReactant = true; rx.BaseReactant = comps[basecompselector.SelectedIndex]; } }; container.CreateAndAddLabelRow("Reaction Balance"); txtEquation = container.CreateAndAddLabelRow2(""); container.CreateAndAddLabelRow("Reaction Phase"); var rxphaseselector = container.CreateAndAddDropDownRow("Reaction Phase", Shared.StringArrays.reactionphase().ToList(), 0, null); switch (rx.ReactionPhase) { case Interfaces.Enums.PhaseName.Vapor: rxphaseselector.SelectedIndex = (0); break; case Interfaces.Enums.PhaseName.Liquid: rxphaseselector.SelectedIndex = (1); break; case Interfaces.Enums.PhaseName.Mixture: rxphaseselector.SelectedIndex = (2); break; } rxphaseselector.SelectedIndexChanged += (sender, e) => { switch (rxphaseselector.SelectedIndex) { case 0: rx.ReactionPhase = Interfaces.Enums.PhaseName.Vapor; break; case 1: rx.ReactionPhase = Interfaces.Enums.PhaseName.Liquid; break; case 2: rx.ReactionPhase = Interfaces.Enums.PhaseName.Mixture; break; } }; container.CreateAndAddLabelRow("Conversion Expression"); container.CreateAndAddLabelRow2("Conversion Expression, % conv = f(T), T in K"); container.CreateAndAddFullTextBoxRow(rx.Expression, (sender, e) => rx.Expression = sender.Text); UpdateEquation(); }
void Initialize() { container.CreateAndAddLabelRow("Reaction ID"); container.CreateAndAddStringEditorRow2("Name", "", rx.Name, (sender, e) => { rx.Name = sender.Text; }); DynamicLayout p1, p2; StackLayout t1; p1 = UI.Shared.Common.GetDefaultContainer(); p2 = UI.Shared.Common.GetDefaultContainer(); p1.Width = 420; p2.Width = 420; t1 = new StackLayout(); t1.Items.Add(new StackLayoutItem(p1)); t1.Items.Add(new StackLayoutItem(p2)); t1.Orientation = Orientation.Horizontal; container.SizeChanged += (sender, e) => { if (p1.ParentWindow != null) { p1.Width = (int)(p1.ParentWindow.Width / 2 - 15); p2.Width = (int)(p2.ParentWindow.Width / 2 - 15); p1.Height = p1.ParentWindow.Height - 170; p2.Height = p1.ParentWindow.Height - 170; } }; container.Add(t1); p1.CreateAndAddLabelRow("Compounds and Stoichiometry (Include / Name / Heat of Formation (kJ/kg) / Stoich. Coeff.)"); var compcontainer = new DynamicLayout(); //compcontainer.BackgroundColor = Colors.White; Double val; foreach (ICompoundConstantProperties comp in flowsheet.SelectedCompounds.Values) { var chk = new CheckBox() { Text = comp.Name, Checked = (rx.Components.ContainsKey(comp.Name) ? true : false) }; chk.CheckedChanged += (sender, e) => { if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, 0, false, 0, 0)); } else { rx.Components.Remove(comp.Name); } UpdateEquation(); }; var sc = new TextBox() { Width = (int)(sf * 50), Text = (rx.Components.ContainsKey(comp.Name) ? rx.Components[comp.Name].StoichCoeff.ToString() : 0.0f.ToString()) }; sc.TextChanged += (sender, e) => { if (Double.TryParse(sc.Text.ToString(), out val)) { sc.TextColor = SystemColors.ControlText; if (!rx.Components.ContainsKey(comp.Name)) { rx.Components.Add(comp.Name, new DWSIM.Thermodynamics.BaseClasses.ReactionStoichBase(comp.Name, Double.Parse(sc.Text), false, 0, 0)); } else { rx.Components[comp.Name].StoichCoeff = double.Parse(sc.Text); } UpdateEquation(); } else { sc.TextColor = Colors.Red; } }; var hf = new TextBox() { Enabled = false, Width = (int)(sf * 100), Text = comp.IG_Enthalpy_of_Formation_25C.ToString("N2") }; compcontainer.Add(new TableRow(chk, null, hf, sc)); } p1.CreateAndAddControlRow(compcontainer); p1.CreateAndAddEmptySpace(); var comps = flowsheet.SelectedCompounds.Values.Select((x) => x.Name).ToList(); comps.Insert(0, ""); p1.CreateAndAddLabelRow("Base Compound"); var basecompselector = p1.CreateAndAddDropDownRow("Base Compound", comps, 0, null); var basecomp = rx.Components.Values.Where((x) => x.IsBaseReactant).FirstOrDefault(); if (basecomp != null) { basecompselector.SelectedIndex = comps.IndexOf(basecomp.CompName); } else { basecompselector.SelectedIndex = 0; } basecompselector.SelectedIndexChanged += (sender, e) => { if (rx.Components.ContainsKey(comps[basecompselector.SelectedIndex])) { foreach (var rxc in rx.Components.Values) { rxc.IsBaseReactant = false; } rx.Components[comps[basecompselector.SelectedIndex]].IsBaseReactant = true; rx.BaseReactant = comps[basecompselector.SelectedIndex]; } }; p1.CreateAndAddLabelRow("Reaction Balance"); txtEquation = p1.CreateAndAddLabelRow2(""); p1.CreateAndAddLabelRow("Reaction Phase"); var rxphaseselector = p1.CreateAndAddDropDownRow("Reaction Phase", Shared.StringArrays.reactionphase().ToList(), 0, null); switch (rx.ReactionPhase) { case Interfaces.Enums.PhaseName.Mixture: rxphaseselector.SelectedIndex = 0; break; case Interfaces.Enums.PhaseName.Vapor: rxphaseselector.SelectedIndex = 1; break; case Interfaces.Enums.PhaseName.Liquid: rxphaseselector.SelectedIndex = 2; break; } rxphaseselector.SelectedIndexChanged += (sender, e) => { switch (rxphaseselector.SelectedIndex) { case 0: rx.ReactionPhase = Interfaces.Enums.PhaseName.Mixture; break; case 1: rx.ReactionPhase = Interfaces.Enums.PhaseName.Vapor; break; case 2: rx.ReactionPhase = Interfaces.Enums.PhaseName.Liquid; break; } }; p1.CreateAndAddLabelRow("Reaction Basis"); var rxbasisselector = p1.CreateAndAddDropDownRow("Reaction Basis", Shared.StringArrays.reactionbasis().ToList(), 0, null); switch (rx.ReactionBasis) { case Interfaces.Enums.ReactionBasis.Activity: rxbasisselector.SelectedIndex = (0); break; case Interfaces.Enums.ReactionBasis.Fugacity: rxbasisselector.SelectedIndex = (1); break; case Interfaces.Enums.ReactionBasis.MassConc: rxbasisselector.SelectedIndex = (2); break; case Interfaces.Enums.ReactionBasis.MassFrac: rxbasisselector.SelectedIndex = (3); break; case Interfaces.Enums.ReactionBasis.MolarConc: rxbasisselector.SelectedIndex = (4); break; case Interfaces.Enums.ReactionBasis.MolarFrac: rxbasisselector.SelectedIndex = (5); break; case Interfaces.Enums.ReactionBasis.PartialPress: rxbasisselector.SelectedIndex = (6); break; } rxbasisselector.SelectedIndexChanged += (sender, e) => { switch (rxbasisselector.SelectedIndex) { case 0: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Activity; break; case 1: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.Fugacity; break; case 2: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassConc; break; case 3: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MassFrac; break; case 4: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarConc; break; case 5: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.MolarFrac; break; case 6: rx.ReactionBasis = Interfaces.Enums.ReactionBasis.PartialPress; break; } }; p2.CreateAndAddLabelRow("Temperature Limits"); var nf = flowsheet.FlowsheetOptions.NumberFormat; var su = flowsheet.FlowsheetOptions.SelectedUnitSystem; p2.CreateAndAddTextBoxRow(nf, "Minimum Temperature (" + su.temperature + ")", rx.Tmin.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmin = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); p2.CreateAndAddTextBoxRow(nf, "Maximum Temperature (" + su.temperature + ")", rx.Tmax.ConvertFromSI(su.temperature), (sender, e) => { if (sender.Text.IsValidDouble()) { rx.Tmax = sender.Text.ToDoubleFromCurrent().ConvertToSI(su.temperature); } }); p2.CreateAndAddLabelRow("Rate Expressions"); p2.CreateAndAddLabelRow2("Reaction Rate Numerator Expression:"); p2.CreateAndAddMultilineTextBoxRow(rx.RateEquationNumerator, false, false, (sender, e) => rx.RateEquationNumerator = sender.Text); p2.CreateAndAddLabelRow2("Reaction Rate Denominator Expression:"); p2.CreateAndAddMultilineTextBoxRow(rx.RateEquationDenominator, false, false, (sender, e) => rx.RateEquationDenominator = sender.Text); p2.CreateAndAddDescriptionRow("Reaction Rate (r) = f(T, Ri, Pi) = Numerator / Denominator"); p2.CreateAndAddDescriptionRow("Expression Variables: Temperature (T) in K, reactant amounts (R1, R2, ..., Rn) and product amounts (P1, P2, ..., Pn in the selected amount units, Reaction Rate (r) in the selected velocity units."); p2.CreateAndAddLabelRow("Units"); var us = new DWSIM.SharedClasses.SystemsOfUnits.Units(); var units = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.molar_conc); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.mass_conc)); units.AddRange(us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.pressure)); units.Insert(0, ""); p2.CreateAndAddDropDownRow("Amount Units", units, units.IndexOf(rx.ConcUnit), (sender, e) => rx.ConcUnit = sender.SelectedValue.ToString()); var units2 = us.GetUnitSet(Interfaces.Enums.UnitOfMeasure.reac_rate_heterog); units2.Insert(0, ""); p2.CreateAndAddDropDownRow("Velocity Units", units2, units2.IndexOf(rx.VelUnit), (sender, e) => rx.VelUnit = sender.SelectedValue.ToString()); UpdateEquation(); }
public void Init() { int w = (int)(sf * 640); int h = (int)(sf * 480); var center = Screen.PrimaryScreen.WorkingArea.Center; center.X -= w / 2; center.Y -= h / 2; Location = new Point(center); ClientSize = new Size(w, h); Maximizable = false; Minimizable = false; Resizable = false; ShowInTaskbar = false; AddComponentInfo(); string imgprefix = "DWSIM.UI.Forms.Resources.Icons."; Title = "AboutDWSIM".Localize(); Icon = Eto.Drawing.Icon.FromResource(imgprefix + "DWSIM_ico.ico"); var layout = new PixelLayout(); string vtext = "Version".Localize() + " " + Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() + "." + Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString(); vtext += " (" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + ")"; var updfile = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + "version.info"; if (File.Exists(updfile)) { int vinfo = 0; int.TryParse(File.ReadAllText(updfile), out vinfo); if (vinfo > 0) { vtext += " Update " + vinfo; } } string crtext = Shared.AssemblyCopyright; layout.Add(new ImageView { Size = new Size((int)(sf * 100), (int)(sf * 100)), Image = new Bitmap(Eto.Drawing.Bitmap.FromResource(imgprefix + "DWSIM_ico.png")) }, 0, 0); layout.Add(new Label { Text = "DWSIM Simulator (Cross-Platform User Interface)", TextAlignment = TextAlignment.Left, Font = SystemFonts.Bold(null, FontDecoration.None) }, (int)(sf * 110), 0); layout.Add(new Label { Text = vtext, TextAlignment = TextAlignment.Left }, (int)(sf * 110), (int)(sf * 20)); layout.Add(new Label { Text = crtext, TextAlignment = TextAlignment.Left }, (int)(sf * 110), (int)(sf * 40)); string osinfo = "", clrinfo = "", meminfo = ""; if (Application.Instance.Platform.IsMac) { var osversion = Environment.OSVersion.Version.ToString(); switch (osversion) { case "11.0.0.0": osinfo = "Mac OS X Lion (v10.7.0)"; break; case "11.4.2.0": osinfo = "Mac OS X Lion (v10.7.5)"; break; case "12.0.0.0": osinfo = "OS X Mountain Lion (v10.8.0)"; break; case "13.0.0.0": osinfo = "OS X Mavericks (v10.9.0)"; break; case "13.4.0.0": osinfo = "OS X Mavericks (v10.9.5)"; break; case "14.0.0.0": osinfo = "OS X Yosemite (v10.10.0)"; break; case "14.5.0.0": osinfo = "OS X Yosemite (v10.10.5)"; break; case "15.0.0.0": osinfo = "OS X El Captain (v10.11.0)"; break; case "15.6.0.0": osinfo = "OS X El Captain (v10.11.6)"; break; case "16.0.0.0": osinfo = "macOS Sierra (v10.12.0)"; break; case "16.1.0.0": osinfo = "macOS Sierra (v10.12.1)"; break; case "16.3.0.0": osinfo = "macOS Sierra (v10.12.2)"; break; case "16.4.0.0": osinfo = "macOS Sierra (v10.12.3)"; break; case "16.5.0.0": osinfo = "macOS Sierra (v10.12.4)"; break; case "16.6.0.0": osinfo = "macOS Sierra (v10.12.5)"; break; case "16.7.0.0": osinfo = "macOS Sierra (v10.12.6)"; break; case "17.0.0.0": osinfo = "macOS High Sierra (v10.13.0)"; break; case "17.4.0.0": osinfo = "macOS High Sierra (v10.13.3)"; break; case "18.0.0.0": osinfo = "macOS Mojave (v10.14.0)"; break; default: osinfo = "macOS (v" + osversion + ")"; break; } } else { osinfo = Environment.OSVersion.ToString(); } clrinfo = SharedClasses.Utility.GetRuntimeVersion(); meminfo = (GC.GetTotalMemory(false) / 1024 / 1024).ToString("#") + " MB managed, " + (Environment.WorkingSet / 1024 / 1024).ToString("#") + " MB total"; var container1 = new DynamicLayout() { Padding = new Padding(10) }; container1.CreateAndAddTwoLabelsRow2("Main Developer:", "Daniel Medeiros ([email protected])"); container1.CreateAndAddTwoLabelsRow2("Contributors:", "Gregor Reichert, Gustavo León and others"); container1.CreateAndAddTwoLabelsRow2("Splash Screen Design:", "Wendel Marcus (www.behance.net/wendelmarcus)"); container1.CreateAndAddTwoLabelsRow2("OS Info:", osinfo); container1.CreateAndAddTwoLabelsRow2("CLR Info:", clrinfo); container1.CreateAndAddTwoLabelsRow2("Memory Usage:", meminfo); container1.CreateAndAddLabelRow("DWSIM is released under the terms of the GNU General Public License (GPL) version 3."); var listcontainer = new GridView { DataStore = components, RowHeight = (int)(sf * 20) }; var col1 = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.Name) }, HeaderText = "Name" }; col1.AutoSize = true; listcontainer.Columns.Add(col1); var col1a = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.Version) }, HeaderText = "Version" }; col1a.AutoSize = true; listcontainer.Columns.Add(col1a); var col1b = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.Year) }, HeaderText = "Year" }; col1b.AutoSize = true; listcontainer.Columns.Add(col1b); var col1c = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.Copyright) }, HeaderText = "Copyright" }; col1c.AutoSize = true; listcontainer.Columns.Add(col1c); var col1d = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.Website) }, HeaderText = "Website" }; col1d.AutoSize = true; listcontainer.Columns.Add(col1d); var col1e = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.License) }, HeaderText = "License" }; col1e.AutoSize = true; listcontainer.Columns.Add(col1e); var col1f = new GridColumn { DataCell = new TextBoxCell { Binding = Binding.Property <ComponentInfo, string>(r => r.LicenseText) }, HeaderText = "License Text" }; col1f.AutoSize = true; listcontainer.Columns.Add(col1f); string gpltext; using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DWSIM.UI.Forms.Resources.TextFiles.gpl-3.0.txt")) using (StreamReader reader = new StreamReader(stream)) { gpltext = reader.ReadToEnd(); } var txt1 = new TextArea { Text = gpltext, ReadOnly = true }; var t1 = new TableLayout(new TableRow(txt1)); var tab1 = new TabPage { Content = container1, Text = "General Information" }; var tab2 = new TabPage { Content = new Scrollable { Content = t1 }, Text = "DWSIM License" }; var tab3 = new TabPage { Content = new Scrollable { Content = listcontainer }, Text = "External Components" }; var tabc = new TabControl(); tabc.Pages.Add(tab1); tabc.Pages.Add(tab2); tabc.Pages.Add(tab3); var tablecontainer = new TableLayout { Padding = new Padding(10), Spacing = new Size(5, 5) }; tablecontainer.Rows.Add(new TableRow(layout)); tablecontainer.Rows.Add(new TableRow(tabc)); Content = tablecontainer; }