Search code examples
c#visual-studiowinformsdatatable

Special Table Containing Labels, Buttons, Text Boxes & Combo Boxes


I am trying to making table in Windows Form app C# which will contains Labels, text boxes, buttons & combo boxes as shown in image below:

enter image description here

I also tried DataGrid View but it does not provide such arrangement like in above image. How I can make such a table programmatically?


Solution

  • How you do this is a matter of programming style, but what I see here are three good candidates for custom UserControl, header, group and effect that each contain TableLayoutPanel. The header and the added groups are inserted into a FlowLayoutPanel on the main form. The single effects are inserted into the table layout panel on the effects group user control.

    This example is going to need some work, but should give you the general idea.

    main

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            flowLayoutPanel.Controls.Add(
                new ScalableHeaderUserControl
                {
                    Width= flowLayoutPanel.Width - SystemInformation.VerticalScrollBarWidth,
                }
            );
            flowLayoutPanel.SizeChanged += (sender, e) =>
            { 
                foreach ( Control control in flowLayoutPanel.Controls )
                {
                    control.Width = flowLayoutPanel.Width - SystemInformation.VerticalScrollBarWidth;
                }
            };
        }
    }
    

    Header

    header

    public partial class ScalableHeaderUserControl : UserControl
    {
        public ScalableHeaderUserControl()
        {
            InitializeComponent();
            labelAdd.Click += onClickAdd;
        }
        private void onClickAdd(object sender, EventArgs e)
        {
            if(Parent is FlowLayoutPanel flowLayoutPanel) 
            { 
                flowLayoutPanel.Controls.Add(new EffectsGroupUserControl
                {
                    Width= flowLayoutPanel.Width - SystemInformation.VerticalScrollBarWidth,
                });
            }
        }
    }
    

    Effect Group

    group

    public partial class EffectsGroupUserControl : UserControl
    {
        public EffectsGroupUserControl()
        {
            InitializeComponent();
            labelAdd.Click += onClickAdd;
            labelTiming.Click += onClickTiming;
            Controls.Add(_timeEditorControl);
            _timeEditorControl.KeyDown += onKeyDownTimeEditor;
        }
        private void onClickAdd(object sender, EventArgs e)
        {
            SingleEffectUserControl effect = new SingleEffectUserControl
            {
                Anchor = (AnchorStyles)0xF,
            };            
            tableLayoutPanel.Controls.Add(effect, 3, _effects.Count);
            tableLayoutPanel.SetColumnSpan(effect, 9);
            _effects.Add(effect);
        }
        private List<SingleEffectUserControl> _effects = new List<SingleEffectUserControl>();
    
        MaskedTextBox _timeEditorControl = new MaskedTextBox()
        {
            Mask = "00:00:000",
            Font = new Font("Segoe UI", 12),
        };
        private void onClickTiming(object sender, EventArgs e)
        {
            if (sender is Control control)
            {
                _timeEditorControl.Tag = control;
                _timeEditorControl.Location = control.Location;
                _timeEditorControl.Show();
                _timeEditorControl.BringToFront();
                _timeEditorControl.Focus();
            }
        }
        private void onKeyDownTimeEditor(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (_timeEditorControl.Tag is Control control)
                {
                    control.Text = _timeEditorControl.Text;
                }
                _timeEditorControl.Hide();
            }
        }
    }
    

    Effect

    single

    public partial class SingleEffectUserControl : UserControl
    {
        public SingleEffectUserControl()
        {
            InitializeComponent();
            comboBoxDevices.SelectedIndex = 0;
            comboBoxEffects.SelectedIndex = 0;
        }
    }