I need a TableLayoutPanel which should be able to change to different grids: 6x6, 10x10 and 16x16. The cells contain a PictureBox with black or white squares as images. Currently I have it where all cells are the same size except those in the last col and row. I am calculating and setting RowStyle to percent in code. E.g 16x16 is 6.25% per row and col.This is the current outcome.
private void AddRowAndCols(int rowColCount)
{
//default is 6x6 so do nothing
if (rowColCount == 6)
return;
else
{
//set row & col count
TlpGameBoard.RowCount = rowColCount;
TlpGameBoard.ColumnCount = rowColCount;
//Calc % each row and col should be
float rowColPercentage = CalculateRowColPercentages(rowColCount);
//clear all current row & col styles as these are still set to the default
TlpGameBoard.ColumnStyles.Clear();
TlpGameBoard.RowStyles.Clear();
//Add new row & col styles
for (int i = 0; i < rowColCount; i++)
{
TlpGameBoard.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, rowColPercentage));
TlpGameBoard.RowStyles.Add(new RowStyle(SizeType.Percent, rowColPercentage));
}
}
I am calculating the % by doing: 100F/numberOfRows as type Float.
The TLP Size is 800, 800.
I have also tried to implement the solution from
Creating same size cells with TableLayoutPanel however this is not working for me.
New to Stack Overflow and programming so apologies for any poor coding/posting practises.
Edit- how do I ensure the cells always stay equal size compared to each other no matter what grid they are? The size of the TLP need to stay the same too.
Thanks
Related
I am trying to add columns and gridsplitters to a grid, but can't get the exact behavior.
After the user specifies where he wants a vertical splitter to appear:
// Get current Col0 width, size new col and existing Col0
double col0Width = LayoutRoot.ColumnDefinitions[0].ActualWidth;
double newCol0Width = col0Width - 5 - pt.X;
LayoutRoot.ColumnDefinitions[0].Width = new GridLength(newCol0Width);
// New Column 0
var c = new ColumnDefinition();
c.Width = new GridLength(pt.X);
LayoutRoot.ColumnDefinitions.Insert(0, c);// Attach GridSplitter to left edge of existing first column
var gss = new GridSplitter();
gss.Background = new SolidColorBrush(Colors.DarkSlateBlue);
gss.Width = 5; gss.Cursor = Cursors.ScrollWE;
gss.ResizeBehavior = GridResizeBehavior.BasedOnAlignment;
gss.HorizontalAlignment = HorizontalAlignment.Left;
LayoutRoot.Children.Add(gss);
// Add to current left-most colunn
Grid.SetColumn(gss, 0);
// Create new column, insert
// New Column 0
var c = new ColumnDefinition();
c.Width = new GridLength(pt.X);
LayoutRoot.ColumnDefinitions.Insert(0, c);
// Move existing content from Col 0 to new Col 1.
I can repeat this and create an arbitrary number of vertical splitters.
The required resize behavior: moving a splitter resizes only the columns immed. to the left and right of the splitter.
The current resize behavior: moving a splitter treats everything to the right of the splitter as one object, expanding or shrinking the column to the left of the splitter, while moving everything to the right. That is, if there are 3 columns, moving the left-most splitter appears to push col 2 to the right and shrinking col 3, without resizing col 2.
(I hope I explained that clearly enough.)
I have tried putting the GridSplitters in their own columns, and tried various GridResizeBehaviors, but haven't found the correct combination.
Any tips would be appreciated....
And a related question: In an event handler for GridSplitter's OnDragDelta, is there a way to stop the splitter from traveling any further in a certain direction? I would like to prevent them from shrinking the right-most column below a certain width, while allowing them to move the splitter back to the left.
Thanks.
As my comment suggested, it looks like the columns need to be '*' sized.
So, after adding the new column and splitter, I fixed up the widths like this (first clumsy cut at solution):
// Get all col widths, set appropriate '*' sizes.
foreach (ColumnDefinition col in LayoutRoot.ColumnDefinitions)
{
colWidths.Add(col.Width);
total += col.Width.Value;
Debug.WriteLine($" Width : {col.Width}");
}
Debug.WriteLine($"{total}");
for (int i = 0; i < LayoutRoot.ColumnDefinitions.Count; i++)
{
double d = colWidths[i].Value;
double ratio = d / total;
int ii = (int) (ratio * 100);
LayoutRoot.ColumnDefinitions[i].Width = new GridLength(ii, GridUnitType.Star);
}
I am creating a chart to export to excel. I need to create several, so I would offset them using the SetPosition() method with the 4 parameters:
SetPosition(int row, int rowoffset in pixel, int col, int coloffset in pixel)
thus
chart.SetPosition(startRow, 350*i, 0, 50);
The problem is that the second row offset parameter stretches the chart by 350*i pixels higher. This must be a bug since the col offset 4th parameter works fine and as expected.
I need to use startRow to start at a specific row cell in the sheet, so I need to get the row offset to work somehow.
Any ideas?
The RowOffset and ColumnOffset have given me trouble as well and I avoid using them in that function. If you look at the source could you can see it doing alot of match with the chart height/width so it seems to do more then just set and top/left position. I have not gone through the effort to fully reverse engineer it.
I just do the math myself. Knowing the default row height in pixels is the only thing that you have to watch out for since this can be customized by the user which you cannot know at design time Here is what I do:
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
//Set specific values to make predictable
const int EXCELCHARTWIDTH = 375;
const int EXCELCHARTHEIGHT = 350;
//Have to assume a standard screen dpi but can be customized by the user
const double EXCELDEFAULTROWHEIGHT = 20.0;
var startCell = (ExcelRangeBase)worksheet.Cells["A1"];
for (var i = 0; i < 10; i++)
{
var chart = worksheet.Drawings.AddChart("chart " + i, eChartType.Pie);
chart.SetSize(EXCELCHARTWIDTH, EXCELCHARTHEIGHT);
chart.SetPosition(startCell.Start.Row, 0, startCell.Start.Column, 0);
var chartcellheight = (int)Math.Ceiling(EXCELCHARTHEIGHT / EXCELDEFAULTROWHEIGHT);
startCell = startCell.Offset(chartcellheight, 0);
}
pck.Save();
}
The offset is an offset within one cell.
So if you have a cell 64 x 20 pixels (default) it should not usually exceed 64 or 20 resp. To set the top left corner of a chart just in the middle of a cell, call:
chart.SetPosition(row , 10, col, 32);
also note that if you read the position from From.RowOff, you need to divide it by 9525
How can i get the left location of a cell in a TableLayoutPanel in pixels on form in C# WinForms .Net v2.0?
Edit: I have seen this but it only has Width and Height.
I added the Widths of every cell to get the Left of a specific cell using this code:
int left = 0;
for(int i = 0; i < theCellIndex; i++)
left += tableLayoutPanel1.GetColumnWidths()[i];
I am trying to recreate a table like this:
I am using the DocX library to manipulate Word files, but I'm having trouble getting the widths right. Trying to set the widths of cells only seems to work when it's not set to the window autofit mode, and it only seems to resize when the specified width is greater than half of the table width, or rather, I can make a cell bigger than half the width but not smaller.
What would be the simplest way to reproduce the intended table?
I found the answer to this myself. In order to properly set the width, you have to loop through each cell in a column and set every width. This will not work with any autofit options selected.
Try this :
Table table = doc.AddTable(2, 2);
table.SetColumnWidth(0, 500);
//first is column index, the second is column width
Bit of an old post to tag to, but after having the same issue it would appear that none of the widths on either the cells or columns actually work, so as a dirty workaround, you can loop through each column and cell adding text to each of the cells, make the text white and finally use the autofit option to autofit to contents eg.
Table t2 = doc.AddTable(2, 8);
for (int i = 0; i < t2.RowCount; i ++)
{
for(int x = 0; x < t2.ColumnCount; x++)
{
t2.Rows[i].Cells[x].Paragraphs.First().Append("12").Color(Color.White);
}
}
t2.AutoFit = AutoFit.Contents;
doc.InsertTable(t2);
This is the way:
Table t = doc.AddTable(1, 5);
t.SetWidthsPercentage(new[] { 20f, 20f, 40f, 10f, 10f }, 500);
The float array sets width percentage for each of the columns, second parameter is the total width of the table.
I don't know if can make it clear otherwise, So here is the code:-
Series series2 = null;
for (int i = 0; i < 4; i++)
{
series2 = chart2.Series.Add(subjectnames[i]);
}
for (int i = 0; i < 4; i++)
{
series2.Points.Add(attemptper[i]);
series2.Points.Add(correctper[i]);
}
Now, I just want to display "attemptper" bars in different color than "correctper" bars. By default they are appearing in greyish-blue color. How do I get it done?
The charts appear all in bluish color. I want them to appear in different colors. I think I haven't added the data correctly to the chart for this to achieve?
You change the color on the series point(index) like this:
Chart1.Series[1].Points[0].Color = Color.Red
Getting the chart to repaint might also take some code, depending on what you're doing. For me, I wanted to animate my chart, building the data point (a column) dynamically as the program ran, showing the status of some work I was doing, which required this:
Chart1.Series.ResumeUpdates()
Chart1.Series[1].Points.Item[0].YValues = Double(1) {MyNewValue, 0}
Chart1.Series[1].Points[0].Color = Color.Red
Chart1.DataBind()
Chart1.Series.Invalidate()
Chart1.Series.SuspendUpdates()
I would suggest adding an extra series to your chart and changing the color set on that.