Click here to Skip to main content
15,886,518 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I want to use a tableLayoutPanel to issue a recite. this should be through runtime and dynamic so that the user can add a row to the recite as many as they want.
please , help
I need to help
thanks
Posted
Comments
BillWoodruff 5-Dec-14 4:40am    
Without specific details it's impossible to know where to begin to assist you.

Is this homework ? What have you tried so far ? What is the source, and structure, of the data that would determine what goes into each row of the TableLayout Panel ?

Have you implemented run-time adding of new Rows to a TableLayoutPanel, and adding new Controls to the new Row ?

Please come back with specific questions and examples from your code.
vajihe.mirzaei 5-Dec-14 6:32am    
I want to have a textbox in every column. some of these textboxes are going to be filled with data coming from barcode reader. Some others are going to be filled via various classes and methods. This is not a homework but a real project. I have an angry client....please help me
BillWoodruff 5-Dec-14 7:00am    
Your client being angry I can't help you with, but I will be happy ... as I'm sure other people here will ... to try and assist you.

But, need to know more about what you have tried already; how far along are you with this: have you created the project, added a TableLayoutPanel, and designed its Rows and Columns ... or are you using code to configure the TableLayoutPanel at run-time ?

"Some others are going to be filled via various classes and methods." Can you say more about this: how would a Class or a method "fill" a Cell (or a TextBox in a Cell) in a TableLayoutPanel ?

Is there a place you're "stuck" with the code right now ?
vajihe.mirzaei 5-Dec-14 7:29am    
I have created the project as well as the tablelayoutpanel. Imagine I have designed the first raw with 7 textbox. this raw (each textbox of standing in a the first raw) is going to be filled with data regarding a goods that is sold; for example one textbox with barcode, the other textbox with the name of a goods, then price, then... But the problem is when the 7th textbox of the first raw is filled by the salesperson, I want the second raw be automatically created without previous design.
BillWoodruff 5-Dec-14 9:10am    
Okay, that's clear, and I think I can assist you with this.

One important question: what is the event ... the trigger ... that you want to signal that the last entry is finished: does the salesperson hit the return key and you intercept that ... or does the salesperson press a button to signal to create a new row ... or does just the salesperson's moving the mouse and clicking somewhere outside the last TextBox trigger the event ?

Another consideration: do you know what the limit of the number of rows is, the maximum ?

I recommend the OP here forget about using a TableLayoutPanel and instead just create a "grid" of TextBoxes, or RichTextBoxes, in a Panel.

Summary: the more I work with the TableLayoutPanel and discover its quirks the less I like it and want to use it. The auto-flow behavior of the TableLayoutPanel seems to be not controllable in a way that you can reliably add new Rows with Controls, and not have the Row/Column order altered in strange ways.

The "last straw" today was discovering that the TableLayoutPanel's method to find a Control based on its Column, Row position (GetControlFromPosition) will not work if the Control is not 'visible; so, to make Controls visible on demand, you have to parse the entire ControlCollection of the TableLayoutPanel.

But, as promised, here's working code that will create a TableLayoutPanel with 51 rows, and 8 columns. The first Row will have Labels showing the Row Number; the first Column will have Labels showing the Column Number and Cells 1,1~7,50 will contain TextBoxes.

I will not support, or answer questions about this code; I may, when and if I have time, extend it, or modify it, and, perhaps, if I reach something usable, and reliable, post a Tip, or article, on CP showing what I've learned.

Initially, only one Row of TextBoxes is displayed: when the user presses the Return/Enter key in the TextBox in the last (eighth) column of ANY Row, the next Row will be made visible.

Because of the side-effects of the auto-flow behavior of the TableLayoutPanel, I do not recommend anyone take on the task of trying to actually delete Rows.
WinForms 
   Controls
       Single Main-Form named 'MainForm
       TableLayoutPanel named 'TestTableLayoutPanel
       Button named 'btnCreateTableLayoutPanel
       ContextMenuStrip named 'ctxMnuStripDeleteRow
0. Design-time settings:

TestTableLayoutPanel:
'RowCount 1
'ColumnCount 1
'GrowStyle AddRows
'CellBorderStyle TableLayoutPanelCellBorderStyle.None

ctxMnuStripDeleteRow: add one Menu Item: 'Delete Row', and create a 'Clicked EventHandler for it. Note: code to delete a row not implemented here.

1. Form-scoped constants:
C#
private const int NRows = 50;
private const int NCols = 7;

private const int RwHeight = 40;
private const int ClWidth = 100;
2. Form-scoped variables:
C#
private int currentRow;
private int currentCol;

private int count = 1;

private TextBox currentTextBox;

private List<textbox> selectedLabels = new List<textbox>();</textbox></textbox>
3. Form Load code:
C#
private void Form1_Load(object sender, EventArgs e)
{
    TestTableLayoutPanel.RowCount = NRows + 1;
    TestTableLayoutPanel.ColumnCount = NCols + 1;
    TestTableLayoutPanel.AutoScroll = true;
}
4. Initializing the TableLayoutPanel:
C#
private void btnCreateLayoutPanel_Click(object sender, EventArgs e)
{
    TestTableLayoutPanel.SuspendLayout();

    TextBox newTextBox;
    Label newLabel;

    TestTableLayoutPanel.RowStyles[0].Height = RwHeight;
    TestTableLayoutPanel.ColumnStyles[0].Width = ClWidth;

    for (int row = 0; row <= NRows; row++)
    {
        TestTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, RwHeight));

        for (int col = 0; col < NCols; col++)
        {
            TestTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, ClWidth));

            // add the column header Label
            if (row == 0)
            {
                newLabel = new Label
                {
                    Margin = new Padding(0),
                    AutoSize = false,
                    Dock = DockStyle.Fill,
                    BackColor = Color.AliceBlue,
                    Text = string.Format("column {0}", (col + 1).ToString()),
                    TextAlign = ContentAlignment.MiddleCenter,
                    TabStop = false
                };

                TestTableLayoutPanel.Controls.Add(newLabel, col + 1, 0);

                // not implemented here
                //newLabel.Click += ColumnHeader_Click;

                continue;
            }

            // add the row header Label
            if (col == 0)
            {
                newLabel = new Label()
                {
                    Margin = new Padding(0),
                    AutoSize = false,
                    Dock = DockStyle.Fill,
                    BackColor = Color.AliceBlue,
                    Text = string.Format("row {0}", row.ToString()),
                    TextAlign = ContentAlignment.MiddleCenter,
                    TabStop = false
                };

                newLabel.ContextMenuStrip = ctxMnuStripDeleteRow;

                TestTableLayoutPanel.Controls.Add(newLabel, 0, row);

                // not implemented here
                newLabel.Click += RowHeader_Click;
            }

            // add the TextBoxes to the interior Cells
            newTextBox = new TextBox()
            {
                AutoSize = false,
                Dock = DockStyle.Fill,
                Margin = new Padding(0),
                Padding = new Padding(0),
                TextAlign = HorizontalAlignment.Center
            };

            newTextBox.Click += CellLabel_Click;

            if (col + 1 == NCols)
            {
                newTextBox.AcceptsReturn = true;
                newTextBox.KeyUp += NewLabelOnKeyUp;
            }

            TestTableLayoutPanel.Controls.Add(newTextBox, col + 1, row);

            if (row > 1) newTextBox.Hide();
        }
    }

    TestTableLayoutPanel.ResumeLayout();
    TestTableLayoutPanel.Refresh();
}
5. Making a new Row visible when the user presses Return in the 7th. TextBox:
C#
private void NewLabelOnKeyUp(object sender, KeyEventArgs keyEventArgs)
{
    if (keyEventArgs.KeyCode != Keys.Enter) return;

    var position = TestTableLayoutPanel.GetPositionFromControl(currentTextBox);

    if (position.Column == NCols)
    {
        currentTextBox.AcceptsReturn = false;

        int row = position.Row + 1;

        TestTableLayoutPanel.RowStyles[row].Height = RwHeight;

        for (int i = 1; i < NCols + 1; i++)
        {
            <big>// See comment !</big>
            foreach (Control cntrl in TestTableLayoutPanel.Controls)
            {
                if (TestTableLayoutPanel.GetCellPosition(cntrl).Column == i)
                {
                    if (TestTableLayoutPanel.GetCellPosition(cntrl).Row == row)
                    {
                        cntrl.Visible = true;
                        break;
                    }
                }
            }
        }
    }
}

private void CellLabel_Click(object sender, EventArgs e)
{
    currentTextBox = sender as TextBox;

    if (currentTextBox == null) return;

    // for future use ... code to track selected Cells ...
}
Comment: there is a bug in the implementation of TableLayoutPanel: when a Control in a Cell is hidden: it cannot be "found" using GetControlFromPosition ! So you see here the hack necessary to find the hidden Controls.

To be continued ?
 
Share this answer
 
v5
Comments
vajihe.mirzaei 9-Dec-14 1:48am    
hello
when to be continued ?
my client have decided to kill me
please help ...
vajihe.mirzaei 9-Dec-14 4:29am    
MR.BillWoodruff
can you continue the solution.
please....
vajihe.mirzaei 9-Dec-14 8:26am    
this solution have bug
newLabel.Click += RowHeader_Click;
RowHeader_Click unkonw my program
I find a new answer
I use datagridview event cell enter
fetch data ,insert cell dynamic , add runtime cell
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900