private void ConfDialog2()
        {
            GLMultiLineTextBox tb = new GLMultiLineTextBox("MLT", new Rectangle(10, 10, 1000, 1000), "this is some text\r\nAnd some more");
            var sizer             = tb.CalculateTextArea(new Size(50, 24), new Size(400, 400));

            tb.Size = sizer.Item1;
            tb.EnableHorizontalScrollBar = sizer.Item2;
            tb.CursorToEnd();

            GLFormConfigurable cform = new GLFormConfigurable("ConfDialog2");

            cform.AddOK("OK");
            cform.AddCancel("Cancel");
            cform.Add(new GLFormConfigurable.Entry("info", tb));
            cform.InstallStandardTriggers();
            cform.Init(new Point(200, 200), "Config Form Test Long Title and even longer one");
            cform.SetMinimumSizeOnAutoSize = true;
            displaycontrol.Add(cform);      // display and autosize
            cform.AutoSize   = false;
            cform.Moveable   = true;
            cform.Resizeable = true;
            tb.Width         = cform.ClientWidth - 10 * 2;
            System.Diagnostics.Debug.WriteLine($"Autosize {cform.AutoSize}");
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Closed += ShaderTest_Closed;

            items.Add(new GLMatrixCalcUniformBlock(), "MCUB");     // create a matrix uniform block

            int front = -20000, back = front + 90000, left = -45000, right = left + 90000, vsize = 2000;

            Vector4[] displaylines = new Vector4[]
            {
                new Vector4(left, -vsize, front, 1), new Vector4(left, +vsize, front, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(right, +vsize, front, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, -vsize, front, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(left, -vsize, front, 1),

                new Vector4(left, -vsize, back, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(left, +vsize, back, 1), new Vector4(right, +vsize, back, 1),
                new Vector4(right, +vsize, back, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, -vsize, back, 1), new Vector4(left, -vsize, back, 1),

                new Vector4(left, -vsize, front, 1), new Vector4(left, -vsize, back, 1),
                new Vector4(left, +vsize, front, 1), new Vector4(left, +vsize, back, 1),
                new Vector4(right, -vsize, front, 1), new Vector4(right, -vsize, back, 1),
                new Vector4(right, +vsize, front, 1), new Vector4(right, +vsize, back, 1),
            };

            GLRenderState rl       = GLRenderState.Lines(1);

            {
                items.Add(new GLFixedShader(System.Drawing.Color.Yellow), "LINEYELLOW");
                rObjects.Add(items.Shader("LINEYELLOW"),
                             GLRenderableItem.CreateVector4(items, PrimitiveType.Lines, rl, displaylines));
            }

            float h = 0;

            if (h != -1)
            {
                items.Add(new GLColorShaderWorld(), "COS-1L");

                int   dist = 1000;
                Color cr   = Color.FromArgb(100, Color.White);
                rObjects.Add(items.Shader("COS-1L"),    // horizontal
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(left, h, back), new Vector3(dist, 0, 0), (back - front) / dist + 1),
                                                                  new Color4[] { cr })
                             );

                rObjects.Add(items.Shader("COS-1L"),
                             GLRenderableItem.CreateVector4Color4(items, PrimitiveType.Lines, rl,
                                                                  GLShapeObjectFactory.CreateLines(new Vector3(left, h, front), new Vector3(right, h, front), new Vector3(0, 0, dist), (right - left) / dist + 1),
                                                                  new Color4[] { cr })
                             );
            }

            GLMatrixCalc mc = new GLMatrixCalc();

            mc.PerspectiveNearZDistance = 1f;
            mc.PerspectiveFarZDistance  = 500000f;

            mc.ResizeViewPort(this, glwfc.Size);                               // must establish size before starting

            displaycontrol           = new GLControlDisplay(items, glwfc, mc); // hook form to the window - its the master, it takes its size fro mc.ScreenCoordMax
            displaycontrol.Focusable = true;                                   // we want to be able to focus and receive key presses.
            displaycontrol.Name      = "displaycontrol";
            displaycontrol.Font      = new Font("Times", 8);

            GLForm pform = new GLForm("Form1", "GL Form demonstration", new Rectangle(0, 0, 1000, 800));

            int taborder = 0;

            if (true)
            {
                string l = "Hello there ggg qqq jjj" + Environment.NewLine + "And the ggg next line";

                GLMultiLineTextBox mtb = new GLMultiLineTextBox("mltb", new Rectangle(10, 10, 400, 200), l);
                mtb.Font = new Font("Ms Sans Serif", 24.25f);
                //mtb.Font = new Font("Arial", 25f);
                mtb.LineColor = Color.Green;
                mtb.EnableVerticalScrollBar   = true;
                mtb.EnableHorizontalScrollBar = true;
                mtb.SetSelection(16 * 2 + 2, 16 * 3 + 4);
                mtb.TabOrder           = taborder++;
                mtb.RightClickMenuFont = new Font("Euro Caps", 14f);
                mtb.FlashingCursor     = false;
                pform.Add(mtb);
            }


            if (true)
            {
                string l = "";
                for (int i = 0; i < 5; i++)
                {
                    string s = string.Format("Line " + i);
                    if (i == 0)
                    {
                        s += "And a much much longer Line which should break the width";
                    }
                    l += s + "\r\n";
                }
                l += "trail ";
                // l = "";

                GLMultiLineTextBox mtb = new GLMultiLineTextBox("mltb", new Rectangle(0, 400, 400, 200), l);
                mtb.Font      = new Font("Ms Sans Serif", 16);
                mtb.LineColor = Color.Green;
                mtb.EnableVerticalScrollBar   = true;
                mtb.EnableHorizontalScrollBar = true;
                mtb.SetSelection(16 * 2 + 2, 16 * 3 + 4);
                mtb.TabOrder           = taborder++;
                mtb.RightClickMenuFont = new Font("Euro Caps", 14f);
                pform.Add(mtb);
                //mtb.FlashingCursor = false;
                //mtb.ReadOnly = true;

                GLMultiLineTextBox mtb2 = new GLMultiLineTextBox("mltb2", new Rectangle(500, 400, 495, 200), l);
                mtb2.Font      = new Font("Ms Sans Serif", 11);
                mtb2.LineColor = Color.Green;
                mtb2.EnableVerticalScrollBar   = true;
                mtb2.EnableHorizontalScrollBar = true;
                mtb2.SetSelection(16 * 2 + 2, 16 * 3 + 4);
                mtb2.TabOrder           = taborder++;
                mtb2.RightClickMenuFont = new Font("Arial", 14f);
                pform.Add(mtb2);
            }

            if (true)
            {
                GLTextBox tb1 = new GLTextBox("TB1", new Rectangle(0, 300, 350, 40), "Text Box Which is a very long string of very many many characters");
                tb1.Font           = new Font("Arial", 12);
                tb1.ReturnPressed += (c1) => { System.Diagnostics.Debug.WriteLine($"Return pressed on text box"); };
                tb1.TabOrder       = taborder++;
                pform.Add(tb1);
            }



            displaycontrol.Add(pform);


            gl3dcontroller = new Controller3D();
            gl3dcontroller.ZoomDistance  = 5000F;
            gl3dcontroller.YHoldMovement = true;
            gl3dcontroller.PaintObjects  = Controller3dDraw;

            gl3dcontroller.KeyboardTravelSpeed = (ms, eyedist) =>
            {
                return((float)ms * 10.0f);
            };

            gl3dcontroller.MatrixCalc.InPerspectiveMode = true;

            if (displaycontrol != null)
            {
                gl3dcontroller.Start(mc, displaycontrol, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F); // HOOK the 3dcontroller to the form so it gets Form events

                displaycontrol.Paint += (o, ts) =>                                                                    // subscribing after start means we paint over the scene, letting transparency work
                {
                    displaycontrol.Render(glwfc.RenderState, ts);                                                     // we use the same matrix calc as done in controller 3d draw
                };
            }
            else
            {
                gl3dcontroller.Start(glwfc, new Vector3(0, 0, 10000), new Vector3(140.75f, 0, 0), 0.5F);     // HOOK the 3dcontroller to the form so it gets Form events
            }
            systemtimer.Start();
        }
Example #3
0
        /// <summary> Construct and display a message box </summary>
        /// <param name="name">Name of message box</param>
        /// <param name="parent">Who to attach to as parent</param>
        /// <param name="location">Location relative to parent. Set to X=int.MinValue for center</param>
        /// <param name="text">Text for message box</param>
        /// <param name="caption">Caption for message box </param>
        /// <param name="buttons">What buttons to display (OK is the default)</param>
        /// <param name="font">What font to display the text in (null = parent font)</param>
        /// <param name="backcolor">Back color of box (null = default)</param>
        /// <param name="forecolor">Fore color (null = default)</param>
        /// <param name="callback">Callback function, called when user has made a selection or hit close (result Cancel). May be null</param>
        /// <param name="moveable">Indicate if dialog should be moveable</param>
        /// <param name="readonlymarked">Indicate if text is editable</param>

        public GLMessageBox(string name,
                            GLBaseControl parent, Point location,
                            string text, string caption,
                            MessageBoxButtons buttons = MessageBoxButtons.OK, Font font = null,
                            Color?backcolor           = null, Color?forecolor = null,
                            Action <GLMessageBox, DialogResultEnum> callback = null,
                            bool moveable       = true,
                            bool readonlymarked = true)
        {
            callbackfunc = callback;

            if (font == null)
            {
                font = new Font("Ms Sans Serif", 12);
            }

            GLFormConfigurable cf = new GLFormConfigurable(name);

            cf.TopMost = true;
            cf.Font    = font;
            if (backcolor != null)
            {
                cf.BackColor = backcolor.Value;
            }
            if (forecolor != null)
            {
                cf.ForeColor = forecolor.Value;
            }

            GLMultiLineTextBox tb = new GLMultiLineTextBox("MLT", new Rectangle(0, 0, 100, 100), text);

            tb.Font      = font;
            tb.BackColor = Color.Transparent;
            tb.ForeColor = cf.ForeColor;
            tb.ReadOnly  = readonlymarked;
            tb.EnableVerticalScrollBar = true;
            tb.CursorToTop();

            const int butwidth            = 80;
            const int butheight           = 20;
            const int textoffsettop       = 10;
            const int butspacingundertext = 8;
            const int butxspacing         = 20;
            const int textmargin          = 4;
            const int windowmargin        = 10;
            Size      availablespace      = parent.Size;

            int windowextrawidth        = textmargin + tb.ClientWidthMargin + cf.AutoSizeClientMargin.Width;
            int availablewidthforclient = availablespace.Width - windowextrawidth - windowmargin * 2;

            int windowsextraheight       = textoffsettop + butspacingundertext + butheight + cf.ClientHeightMargin + cf.AutoSizeClientMargin.Height;
            int availableheightforclient = availablespace.Height - windowsextraheight - windowmargin * 2;

            var estsize = tb.CalculateTextArea(new Size(20, 24), new Size(availablewidthforclient, availableheightforclient));

            tb.Bounds = new Rectangle(textmargin, textoffsettop, estsize.Item1.Width, estsize.Item1.Height);
            tb.EnableHorizontalScrollBar = estsize.Item2;

            int butright = tb.Bounds.Right - butwidth;
            int butline  = tb.Bounds.Bottom + butspacingundertext;

            if (buttons == MessageBoxButtons.AbortRetryIgnore)
            {
                cf.Add(new GLFormConfigurable.Entry("Ignore", typeof(GLButton), "Ignore", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.Ignore)
                {
                    TabOrder = 0, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("Retry", typeof(GLButton), "Retry", new Point(butright - butwidth - butxspacing, butline), new Size(butwidth, butheight), null, DialogResultEnum.Retry)
                {
                    TabOrder = 1, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("OK", typeof(GLButton), "OK", new Point(butright - (butwidth + butxspacing) * 2, butline), new Size(butwidth, butheight), null, DialogResultEnum.OK)
                {
                    TabOrder = 2, Anchor = AnchorType.AutoPlacement
                });
            }
            else if (buttons == MessageBoxButtons.OKCancel)
            {
                cf.Add(new GLFormConfigurable.Entry("Cancel", typeof(GLButton), "Cancel", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.Cancel)
                {
                    TabOrder = 0, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("OK", typeof(GLButton), "OK", new Point(butright - butwidth - butxspacing, butline), new Size(butwidth, butheight), null, DialogResultEnum.OK)
                {
                    TabOrder = 1, Anchor = AnchorType.AutoPlacement
                });
            }
            else if (buttons == MessageBoxButtons.RetryCancel)
            {
                cf.Add(new GLFormConfigurable.Entry("Retry", typeof(GLButton), "Retry", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.Retry)
                {
                    TabOrder = 0, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("OK", typeof(GLButton), "OK", new Point(butright - butwidth - butxspacing, butline), new Size(butwidth, butheight), null, DialogResultEnum.OK)
                {
                    TabOrder = 1, Anchor = AnchorType.AutoPlacement
                });
            }
            else if (buttons == MessageBoxButtons.YesNo)
            {
                cf.Add(new GLFormConfigurable.Entry("No", typeof(GLButton), "No", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.No)
                {
                    TabOrder = 0, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("Yes", typeof(GLButton), "Yes", new Point(butright - butwidth - butxspacing, butline), new Size(butwidth, butheight), null, DialogResultEnum.Yes)
                {
                    TabOrder = 1, Anchor = AnchorType.AutoPlacement
                });
            }
            else if (buttons == MessageBoxButtons.YesNoCancel)
            {
                cf.Add(new GLFormConfigurable.Entry("Cancel", typeof(GLButton), "Cancel", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.Cancel)
                {
                    TabOrder = 0, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("No", typeof(GLButton), "No", new Point(butright - butwidth - butxspacing, butline), new Size(butwidth, butheight), null, DialogResultEnum.No)
                {
                    TabOrder = 1, Anchor = AnchorType.AutoPlacement
                });
                cf.Add(new GLFormConfigurable.Entry("Yes", typeof(GLButton), "Yes", new Point(butright - (butwidth + butxspacing) * 2, butline), new Size(butwidth, butheight), null, DialogResultEnum.Yes)
                {
                    TabOrder = 2, Anchor = AnchorType.AutoPlacement
                });
            }
            else
            {
                cf.Add(new GLFormConfigurable.Entry("OK", typeof(GLButton), "OK", new Point(butright, butline), new Size(butwidth, butheight), null, DialogResultEnum.OK));
            }

            cf.Add(new GLFormConfigurable.Entry("MTL-MB", tb));

            if (location.X == int.MinValue)
            {
                cf.InitCentered(caption);
            }
            else
            {
                cf.Init(location, caption);
            }

            cf.Tag      = this;
            cf.Trigger += (cfg, en, ctrlname, args) =>
            {
                if (ctrlname == "Close")
                {
                    if (!sentcallback)          // close gets called if form is closing, but we may have already below sent a callbackfunc
                    {
                        callbackfunc?.Invoke(this, DialogResultEnum.Cancel);
                    }
                }
                else if (ctrlname == "Escape")
                {
                    cf.DialogResult = DialogResultEnum.Abort;
                    callbackfunc?.Invoke(this, cf.DialogResult);
                    sentcallback = true;
                    cf.Close();
                }
                else
                {
                    cf.DialogResult = (DialogResultEnum)en.Tag;
                    callbackfunc?.Invoke(this, cf.DialogResult);
                    sentcallback = true;
                    cf.Close();
                }
            };

            parent.AddToDesktop(cf);      // this autosizes the form

            cf.AutoSize = false;          // now we turn autosize off, and allow it to move
            cf.Moveable = moveable;
            tb.Width    = cf.ClientWidth - textmargin * 2;
        }
        private void InitInt(string caption, Object callertag)
        {
            this.callertag   = callertag;    // passed back to caller via trigger
            this.Text        = caption;
            this.FormClosed += (a) => {
                Trigger?.Invoke(this, null, "Close", this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
            };

            SuspendLayout();

            for (int i = 0; i < entries.Count; i++)
            {
                Entry ent = entries[i];

                bool oursmade = ent.Control == null;

                if (oursmade)
                {
                    ent.Control      = (GLBaseControl)Activator.CreateInstance(ent.ControlType);
                    ent.Control.Name = ent.Name;
                    ent.Control.SetNI(ent.Location, ent.Size);
                    ent.Control.Anchor   = ent.Anchor;
                    ent.Control.AutoSize = ent.AutoSize;
                }

                GLBaseControl control = ent.Control;
                control.Tag      = ent; // point control tag at ent structure
                control.TabOrder = ent.TabOrder;

                if (control is GLLabel)
                {
                    var l = control as GLLabel;
                    if (oursmade)
                    {
                        l.Text = ent.Text;
                    }

                    if (ent.TextAlign.HasValue)
                    {
                        l.TextAlign = ent.TextAlign.Value;
                    }
                }
                else if (control is GLNumberBoxFloat)      // must be before MLTB
                {
                    GLNumberBoxFloat cb = control as GLNumberBoxFloat;

                    if (oursmade)
                    {
                        cb.Minimum = (float)ent.NumberBoxDoubleMinimum;
                        cb.Maximum = (float)ent.NumberBoxDoubleMaximum;
                        float?v = ent.Text.InvariantParseFloatNull();
                        cb.Value = v.HasValue ? v.Value : cb.Minimum;
                        if (ent.NumberBoxFormat != null)
                        {
                            cb.Format = ent.NumberBoxFormat;
                        }
                    }

                    cb.ReturnPressed += (box) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, ":Return", this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                    cb.ValidityChanged += (box, b) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, "Validity:" + b.ToString(), this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }
                else if (control is GLNumberBoxDouble)      // must be before MLTB
                {
                    GLNumberBoxDouble cb = control as GLNumberBoxDouble;

                    if (oursmade)
                    {
                        cb.Minimum = ent.NumberBoxDoubleMinimum;
                        cb.Maximum = ent.NumberBoxDoubleMaximum;
                        double?v = ent.Text.InvariantParseDoubleNull();
                        cb.Value = v.HasValue ? v.Value : cb.Minimum;
                        if (ent.NumberBoxFormat != null)
                        {
                            cb.Format = ent.NumberBoxFormat;
                        }
                    }

                    cb.ReturnPressed += (box) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, ":Return", this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                    cb.ValidityChanged += (box, b) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, "Validity:" + b.ToString(), this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }
                else if (control is GLNumberBoxLong)        // must be before MLTB
                {
                    GLNumberBoxLong cb = control as GLNumberBoxLong;
                    if (oursmade)
                    {
                        cb.Minimum = ent.NumberBoxLongMinimum;
                        cb.Maximum = ent.NumberBoxLongMaximum;
                        long?v = ent.Text.InvariantParseLongNull();
                        cb.Value = v.HasValue ? v.Value : cb.Minimum;
                        if (ent.NumberBoxFormat != null)
                        {
                            cb.Format = ent.NumberBoxFormat;
                        }
                    }

                    cb.ReturnPressed += (box) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, "Return", this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                    cb.ValidityChanged += (box, s) =>
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, "Validity:" + s.ToString(), this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }

                else if (control is GLMultiLineTextBox)   // also TextBox as its inherited
                {
                    GLMultiLineTextBox tb = control as GLMultiLineTextBox;

                    if (oursmade)
                    {
                        tb.Text             = ent.Text;
                        tb.ClearOnFirstChar = ent.ClearOnFirstChar;
                        tb.ReadOnly         = ent.ReadOnly;
                    }

                    tb.ReturnPressed += (box) =>        // only works for text box
                    {
                        Entry en = (Entry)(box.Tag);
                        Trigger?.Invoke(this, en, "Return", this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }
                else if (control is GLButton)
                {
                    GLButton b = control as GLButton;
                    if (oursmade)
                    {
                        b.Text = ent.Text;
                    }

                    if (ent.TextAlign.HasValue)
                    {
                        b.TextAlign = ent.TextAlign.Value;
                    }

                    b.Click += (sender, ev) =>
                    {
                        Entry en = (Entry)(((GLBaseControl)sender).Tag);
                        Trigger?.Invoke(this, en, en.Name, this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };

                    b.Return += (sender) =>
                    {
                        Entry en = (Entry)(((GLBaseControl)sender).Tag);
                        Trigger?.Invoke(this, en, en.Name, this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }
                else if (control is GLCheckBox)
                {
                    GLCheckBox cb = control as GLCheckBox;
                    if (oursmade)
                    {
                        cb.Checked = ent.Checked;
                    }
                    cb.CheckChanged = (sender) =>
                    {
                        Entry en = (Entry)(((GLBaseControl)sender).Tag);
                        Trigger?.Invoke(this, en, en.Name, this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                    };
                }
                else if (control is GLDateTimePicker)
                {
                    GLDateTimePicker dt = control as GLDateTimePicker;
                    if (oursmade)
                    {
                        DateTime t;
                        if (DateTime.TryParse(ent.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out t))     // assume local, so no conversion
                        {
                            dt.Value = t;
                        }
                    }

                    switch (ent.CustomDateFormat.ToLowerInvariant())
                    {
                    case "short":
                        dt.Format = GLDateTimePicker.DateTimePickerFormat.Short;
                        break;

                    case "long":
                        dt.Format = GLDateTimePicker.DateTimePickerFormat.Long;
                        break;

                    case "time":
                        dt.Format = GLDateTimePicker.DateTimePickerFormat.Time;
                        break;

                    default:
                        dt.CustomFormat = ent.CustomDateFormat;
                        break;
                    }
                }
                else if (control is GLComboBox)
                {
                    GLComboBox cb = control as GLComboBox;

                    if (oursmade)
                    {
                        cb.Items.AddRange(ent.ComboBoxItems);
                        if (cb.Items.Contains(ent.Text))
                        {
                            cb.SelectedItem = ent.Text;
                        }
                    }

                    cb.SelectedIndexChanged += (sender) =>
                    {
                        GLBaseControl ctr = (GLBaseControl)sender;
                        if (ctr.Enabled)
                        {
                            Entry en = (Entry)(ctr.Tag);
                            Trigger?.Invoke(this, en, en.Name, this.callertag);       // pass back the logical name of dialog, the name of the control, the caller tag
                        }
                    };
                }


                Add(control);
            }

            ResumeLayout();
        }