C# filling TableLayoutPanel cells from left to right - c#

I am working on a windows form app which primarily consists of a TableLayoutPanel with 8 columns and 9 rows. I have been able to fill each of the cells like so:
for (int row = 0; row < TableLayoutPanel.RowCount; row++) {
for (int column = 0; column < TableLayoutPanel.ColumnCount; column++) {
PictureBox pictureBox = new PictureBox();
pictureBox.BackColor = Color.Blue;
TableLayoutPanel.Controls.Add(pictureBox, column, row);
pictureBox.Dock = DockStyle.Fill;
pictureBox.Margin = new Padding(1);
}
However this method starts from the top than goes left to right downwards like:
1 2 3
4 5 6
My aim is to fill the TableLayoutPanel like:
6 5 4
1 2 3
I don't know if this is possible but is there a way to do fill the TableLayoutPanel cells in this fashion?

Don't worry guys I figured out how to do it. What I did was that I started from the bottom row of the TableLayoutPanel (in my case was row = 8) and worked up from there. I than determined if the row values were odd or even in which case I would change the direction. Here is the solution.
for (int row = TableLayoutPanel.RowCount-1; row >= 0; row--) {
if (row % 2 == 0) { //if even
for (int column = 0; column < TableLayoutPanel.ColumnCount; column++) {
PictureBox pictureBox = new PictureBox();
pictureBox.BackColor = Color.Blue;
TableLayoutPanel.Controls.Add(pictureBox, column, row);
pictureBox.Dock = DockStyle.Fill;
pictureBox.Margin = new Padding(1);
} else {
for (int column = TableLayoutPanel.ColumnCount-1; column >= 0; column--) {
PictureBox pictureBox = new PictureBox();
pictureBox.BackColor = Color.Blue;
TableLayoutPanel.Controls.Add(pictureBox, column, row);
pictureBox.Dock = DockStyle.Fill;
pictureBox.Margin = new Padding(1);
}
}

Try to replace your for loops with:
for (int row = TableLayoutPanel.RowCount - 1, c0 = 0, c1 = TableLayoutPanel.ColumnCount - 1, cs = 1; row >= 0 ; row--, c0 ^= c1, c1 ^= c0, c0 ^= c1, cs *= -1)
{
for (int column = c0; column != c1 + cs; column += cs)
{
...

Related

With Xamarin ... How do I SUM two cells inside the grid for the same row or for several rows?

Please help, as I made a small project with Xamarin
It is a connection to a SQl server database and then filling the Datatable with data and then displaying the data in Grid .. which contains Entries that have been added programmatically and not in XAML ... This means that Entries do not have Names or IDs assigned to each one of them .. Even these At the moment it is working fine...and the data is being recalled properly
But as you know inside Grid there are Rows and Columns and I need to add or multiply the contents of Entries in the same row or add the contents of a column or columns
How do I SUM two cells inside the grid for the same row or for several rows?
And does the grid fit with that or do I have to choose another rendering too
Notes ::: >>> Maingrid is my Grid
////// define the number of rows according to the number of item you have
for (int i = 0; i < dt.Rows.Count; i++)
{
MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
}
//////// defining column number (in this case 3)
for (int j = 0; j < dt.Columns.Count; j++)
{
MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
}
////////// adding the items to the grid (3 column , RN rows)
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int num = 0; num < dt.Columns.Count; num++)
{
Entry entry = new Entry();
entry.Text = dt.Rows[i][num].ToString();
entry.TextColor = Color.Blue;
entry.BackgroundColor = Color.GhostWhite;
entry.HorizontalOptions = LayoutOptions.FillAndExpand;
entry.HorizontalTextAlignment = TextAlignment.Center;
entry.VerticalTextAlignment = TextAlignment.Center;
entry.Keyboard = Keyboard.Numeric;
entry.TextChanged += MyEntry_TextChanged;
entry.WidthRequest = 50;
MainGrid.Children.Add(entry, num , i);
}
You can get the two cells at first. And then get the sum of the two cell and set it as another cells value.
You can try the following code:
public void GetSum()
{
var rowcount = MainGrid.RowDefinitions.Count;
for( int i = 0; i < rowcount; i++ )
{
Entry A = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 0 ).FirstOrDefault();
Entry B = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 1 ).FirstOrDefault();
Entry C = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 2 ).FirstOrDefault();
C.Text = (int.Parse(A.Text) + int.Parse(B.Text)).ToString();
}
}
The code above can make your MainGrid like a grid in the picture below:
In addition, the point is this line MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 0 ).FirstOrDefault(). You can use it to get any child in the grid if you know the child view's row index and column index.

TableLayoutPanel not showing all data

I have table layout panel. Inside each one I create a Panel to insert two different controls in each cell.
I want to fill TableLayoutPanel with all my data, in this case I have 16 should have 16 different cells. So I try:
private void AddRow(IList<DeliveryBreakdownGetViewModel> rModel)
{
tpnlDeliveryBreakdown.RowCount = rModel.Count / 4; //rModel count = 16
tpnlDeliveryBreakdown.ColumnCount = 4;
var row = 0;
var column = 0;
var fullRow = 1;
for (int i = 0; i < rModel.Count; i++)
{
var panel = new Panel();
Labels.Add(rModel[i].DesignGroupName);
var label = new Label
{
AutoSize = true,
Name = "label" + Labels.Count,
Text = rModel[i].DesignGroupName,
Location = new Point(12, YPos)
};
this.Controls.Add(label);
tpnlDeliveryBreakdown.Controls.Add(panel, column, row);
panel.Controls.Add(label);
DeliveryBreakdownLabelsModel.Add(label);
var numericUpDown = new NumericUpDown
{
Name = "numericUpDown" + Labels.Count,
Maximum = decimal.MaxValue,
Minimum = decimal.MinValue,
Value = Decimal.Round(rModel[i].ContractedAmount, 2),
Location = new Point(12, YPos),
Size = new Size(60, 19),
DecimalPlaces = 2,
Tag = rModel[i].DesignGroupId
};
this.Controls.Add(numericUpDown);
panel.Controls.Add(numericUpDown);
DeliveryBreakdownNumericUpDownModel.Add(numericUpDown);
if (fullRow % 4 == 0)
{
row++;
}
fullRow++;
if(column == 4)
{
column = 0;
}
else
{
column++;
}
}
}
But it only show 2 columns and 7 cells:
Why is not showing all cells and it only show 2 columns instead 4. Regards

how can I dynamically allocate a number of datagridview in tablelayout?

I want dynamic allocation datagridview in tablelayout.
For example, I choose number of grids, (2, 4, 9, 16...)
next, create this number of datagridview controls and place them in tablelayout.
Example:
So, how can I allocate dynamically allocate a number of Datagridview using one tablelayout
i created new Form (Form1), added new TableLayoutPanel with name t and added this code for form contructor:
public Form1()
{
InitializeComponent();
int row = 1; // number of rows
int col = 2; // number of columns (change them to see effect)
var grids = new DataGridView[row,col];
// create rows and set their height
t.RowCount = row;
t.RowStyles.Clear();
for (int r = 0; r < row; r++)
{
var style = new RowStyle();
style.SizeType = SizeType.Percent;
style.Height =(float)(1.0/row);
t.RowStyles.Add(style);
}
// create columns and set their width
t.ColumnCount = col;
t.ColumnStyles.Clear();
for (int c = 0; c < col; c++)
{
var style = new ColumnStyle();
style.SizeType = SizeType.Percent;
style.Width = (float)(1.0 / col);
t.ColumnStyles.Add(style);
}
// dynamically add grid in necessary place in layout
for(int r = 0; r<row; r++)
for (int c = 0; c < col; c++)
{
grids[r,c] = new DataGridView()
{
Dock = DockStyle.Fill,
};
t.Controls.Add(grids[r, c], c, r);
}
}

Get number of blank textboxes

I am writing crossWord program
First, the user must enter a number "n" , and create a n * n table with TextBoxes that are in white color and blank.
After building the table, the user clicks on several houses and the house backcolor change to black.
My question is after this steps, how many TextBoxes are in the Black color, how many are white, How can I detect the maximum number of consecutive white text box without any black on them, in horizontally or vertically columns,to paste words that match to them!
In above table, form must detect that 5 is max of white consecutive textboxes in second horizontal line or in second vertical line, after user fill them must show 4 is max in first horizontal line, and go on to end...
Here is my code snippents:
private void CreateCrossTable()
{
int count = Convert.ToInt32(textBox1.Text.Trim());
if (count > 10)
count = 10;
int x = 100, y = 100;
const int value = 100;
for (int i = 1; i <= count; i++)
{
for (int j = 1; j <= count; j++)
{
x = value + (j * 20);
TextBox tb = new TextBox();
tb.Name = "txtbox" + i + "-" + j;
tb.Location = new Point(x, y);
tb.Size = new System.Drawing.Size(20, 20);
tb.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.txtMouseDoubleClick);
Controls.Add(tb);
}
y = value + (i * 20);
}
}
private void txtMouseDoubleClick(object sender, MouseEventArgs e)
{
TextBox tb = (TextBox)sender;
tb.BackColor = Color.Black;
tb.Enabled = false;
tb.Text = "|";
}
so , now I use LINQ to get All white textbox like this:
IEnumerable<TextBox> FreeItems = frm.Controls.OfType<TextBox>().Where(I => I.BackColor != Color.Black);
how can I get items those who are white and diffrence of X location of them not more than 20!
Try following example
private void findConsecutive()
{
var vertical = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
orderby cnt.Top
select cnt.Top).Distinct().ToArray();
var horizontal = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
orderby cnt.Left
select cnt.Left).Distinct().ToArray();
List<int> vList = new List<int>();
int iIndex = 0;
foreach (int top in vertical)
{
vList.Add(0);
int vIndex = 0;
int iConsecutive = 0;
int iLastLeft = -1;
var Item = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
&& (cnt.Top.Equals(top))
select (TextBox)cnt).ToArray();
foreach (TextBox txt in Item)
{
if ((iLastLeft + txt.Width) < txt.Left && iLastLeft > -1)
{
if (iConsecutive > vList[iIndex])
vList[iIndex] = iConsecutive;
iConsecutive = 0;
}
iConsecutive++;
iLastLeft = txt.Left;
vIndex++;
}
if (iConsecutive > vList[iIndex])
vList[iIndex] = iConsecutive;
iIndex++;
}
int MaxConsicutiveIndex = vList.IndexOf(vList.Max());
}
EDITED
Above code will retrieve the Line Index of Maximum Consicutive White box in Horizontal Line.
You'll need a layout container that will allow you to arrange cells dynamically. A table should work.
For each cell store the x,y position in the tag property.
When the user clicks on a specific cell it will be easy to write a method that gives you a collection of cells or text boxes that are in the same row. Or if you want to find the answer after clicking a button you'll have to loop through all the rows.
This should get you in a good place to finish the rest.

Drawing a vertical line in a gridview cell

I want to demarcate the values of a given cell in a gridview into three without using "|" but a vertical line the length of the column in the gridview.
for (int i = 0; i < subjectCount; i++)
{
TableCell totals = new TableHeaderCell();
totals.ColumnSpan = grid.Columns.Count - 1;
totals.BackColor = System.Drawing.SystemColors.ControlDark;// System.Drawing.Color.FromArgb(#c0c0c0);
totals.ForeColor = System.Drawing.Color.White;
totals.Font.Size = FontUnit.Medium;
totals.Font.Bold = true;
//totals.Text = "40|60%|100%"; would love to display and image in between them like 40-vertical image-60-vertical image-100
totals.Text = "40 | 60 | 100";
row.Cells.Add(totals);
t.Rows.AddAt(1, row);
}

Categories

Resources