Click here to Skip to main content
14,971,029 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 ?
vajihe.mirzaei 7-Dec-14 0:59am
   
please answer me ...
BillWoodruff 7-Dec-14 3:09am
   
Will try and post code to assist you today, or tonight. I'm on GMT+7-hours time.
vajihe.mirzaei 7-Dec-14 3:49am
   
thank you very much indeed
BillWoodruff 7-Dec-14 7:08am
   
Once again: 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 ?

Also, is the user allowed to somehow remove a Row ... the last Row created ? ... any Row ?
vajihe.mirzaei 7-Dec-14 7:44am
   
the event is "leave the TextBox in the last cell (7th cell)",
the trigger is "add a new raw identical with the first raw",
the salesperson hits the return key and the new raw gets created,
any raw should be able to be deleted or edited.
Thanx a million
BillWoodruff 7-Dec-14 8:16am
   
Hi, I took the code that creates a useful TableLayoutPanel from a project I did a few years ago, and modified it so it supports creating new Rows at run-time in the way you want, but I am finding some "strange things" in testing it, and the modifications I've made to deal with those "strange things" are getting more complex than I like.

The original implementation I did had no run-time implementation of Controls in the Cells; it was configured at design-time.

It appears adding deleting rows will make it even more complex.

I worry that if I put this code out there, it may not meet your needs without further modifications, and I cannot be available to keep working on this code since that goes beyond my role of teaching, and assisting here. And, I don't like the thought of your trying to meet a deadline and being stuck using my code :)

Let me ask you a question: what about the idea of presenting the user with a fully initialized (one TextBox in each of the 7 x 50 Cells) TableLayoutPanel, let the user fill in what they need; then, when the user clicks render/print, go through the Cells, and write formatted text into a RichTextBox so you have a professional looking result.
vajihe.mirzaei 7-Dec-14 10:13am
   
yes I agree with you and (what about the idea of presenting the user with a fully initialized (one TextBox in each of the 7 x 50 Cells) TableLayoutPanel, let the user fill in what they need; then, when the user clicks render/print, go through the Cells, and write formatted text into a RichTextBox so you have a professional looking result.)
and waiting ...
BillWoodruff 7-Dec-14 10:26am
   
I've run out of "mental energy" for today, but tomorrow I will post some code, promise.

What you will have to do is implement going through all the cells and putting the Text you want, formatted as you wish (Color, Font, FontSize, FontStyle), into the RichTextBox, and displaying it in whatever way you wish (centered, right- left- justified, in a separate Form ?), adding carriage-returns when you have a Row with all its TextBoxes with no entry, etc.

And, you'll have to deal with printing the formatted contents of the RichTextBox if printing is one of your goals.

fyi: you can find some good articles here on CodeProject that have Controls that support RTF and printing.
vajihe.mirzaei 6-Dec-14 4:25am
   
yes it's true ;
I know the limit of the number of rows is 50.
please answer the question with an example.

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 ?
   
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
   

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