I have auto-sized 2x2 table layout and long auto-sized labels in each cell.
This layout is in other table layout with no-auto-sized cells.
Minimal project to reproduce the problem:
using System;
using System.Windows.Forms;
namespace TestForms {
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TestForm());
}
}
class TestForm : Form {
public TestForm() {
var childPanel = new TableLayoutPanel();
var label8 = new Label();
var label9 = new Label();
var label10 = new Label();
var label7 = new Label();
var rootPanel = new TableLayoutPanel();
childPanel.AutoSize = true;
childPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
childPanel.BackColor = System.Drawing.Color.Silver;
childPanel.ColumnCount = 2;
childPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
childPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
childPanel.Controls.Add(label8, 1, 0);
childPanel.Controls.Add(label9, 0, 1);
childPanel.Controls.Add(label10, 1, 1);
childPanel.Controls.Add(label7, 0, 0);
childPanel.Dock = DockStyle.Top;
childPanel.RowCount = 2;
childPanel.RowStyles.Add(new RowStyle());
childPanel.RowStyles.Add(new RowStyle());
label8.AutoSize = true;
label8.Text = "2ggggggggggggggggg";
label9.AutoSize = true;
label9.Text = "label9";
label10.AutoSize = true;
label10.Text = "label10";
label7.AutoSize = true;
label7.Text = "label7";
rootPanel.ColumnCount = 1;
rootPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
rootPanel.Controls.Add(childPanel, 0, 0);
rootPanel.Dock = DockStyle.Fill;
rootPanel.RowCount = 1;
rootPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
ClientSize = new System.Drawing.Size(205, 197);
Controls.Add(rootPanel);
}
}
}
I get the following result:
Why last row got the wrong height? Is there a workaround?
Interestingly, seems like you have hit some bug since it doesn't happen if some of the labels AutoSize is false, or making the first column style SizeType.AutoSize etc.
You can use the following workaround. It's ugly, but that's the only way I've found. The idea is to add invisible row containing fake Label with AutoSize set to false. For instance, after setting up the normal layout, add the following lines:
childPanel.RowCount++;
childPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 0));
childPanel.Controls.Add(new Label { AutoSize = false }, 0, childPanel.RowCount - 1);
Related
I'm using LiveCharts in WinForms. Reason why I'm not using WPF is because I don't want to rewrite the GUI in WPF, so I'm trying to see if I can make LiveCharts work in WinForms.
I'm saving the LiveCharts control as an image to a PDF, so the title needs to be on the chart itself.
I cannot find any functionality for adding a title on the chart. What I have tried is the following:
VisualElement title = new VisualElement();
title.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
title.VerticalAlignment = System.Windows.VerticalAlignment.Top;
title.X = 0.5;
title.Y = maxYVal;
TextBlock titleText = new TextBlock();
titleText.Text = chartName;
var newTitleFont = HelperFunctions.NewTypeFaceFromFont(titleFont);
titleText.FontFamily = newTitleFont.FontFamily;
titleText.FontStyle = newTitleFont.Style;
titleText.FontSize = titleFont.Size;
title.UIElement = titleText;
cartChart.VisualElements.Add(title);
The above code only adds a label on the chart itself (within the y axis range). The title needs to be independent (above the y axis). Any idea?
This seems to do the trick:
public static TableLayoutPanel AddTitleToChart(Control chart,string title, System.Drawing.Font titleFont)
{
Label label = new Label();
label.AutoSize = true;
label.Dock = System.Windows.Forms.DockStyle.Fill;
label.Font = titleFont;
label.Location = new System.Drawing.Point(3, 0);
label.Name = "label1";
label.Size = new System.Drawing.Size(1063, 55);
label.TabIndex = 0;
label.Text = title;
label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
label.BackColor = chart.BackColor;
chart.Dock = System.Windows.Forms.DockStyle.Fill;
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
tableLayoutPanel.AutoSize = true;
tableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
tableLayoutPanel.BackColor = System.Drawing.Color.White;
tableLayoutPanel.ColumnCount = 1;
tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1069F));
tableLayoutPanel.Controls.Add(label, 0, 0);
tableLayoutPanel.Controls.Add(chart, 0, 1);
tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
tableLayoutPanel.Location = new System.Drawing.Point(0, 0);
tableLayoutPanel.Name = "tableLayoutPanel1";
tableLayoutPanel.RowCount = 2;
tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel.Size = new System.Drawing.Size(1069, 662);
tableLayoutPanel.TabIndex = 2;
return (tableLayoutPanel);
}
I'm using LiveCharts in WinForms. Reason why I'm not using WPF is because I don't want to rewrite the GUI in WPF, so I'm trying to see if I can make LiveCharts work in WinForms.
I'm saving the LiveCharts control as an image to a PDF, so the title needs to be on the chart itself.
I cannot find any functionality for adding a title on the chart. What I have tried is the following:
VisualElement title = new VisualElement();
title.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
title.VerticalAlignment = System.Windows.VerticalAlignment.Top;
title.X = 0.5;
title.Y = maxYVal;
TextBlock titleText = new TextBlock();
titleText.Text = chartName;
var newTitleFont = HelperFunctions.NewTypeFaceFromFont(titleFont);
titleText.FontFamily = newTitleFont.FontFamily;
titleText.FontStyle = newTitleFont.Style;
titleText.FontSize = titleFont.Size;
title.UIElement = titleText;
cartChart.VisualElements.Add(title);
The above code only adds a label on the chart itself (within the y axis range). The title needs to be independent (above the y axis). Any idea?
This seems to do the trick:
public static TableLayoutPanel AddTitleToChart(Control chart,string title, System.Drawing.Font titleFont)
{
Label label = new Label();
label.AutoSize = true;
label.Dock = System.Windows.Forms.DockStyle.Fill;
label.Font = titleFont;
label.Location = new System.Drawing.Point(3, 0);
label.Name = "label1";
label.Size = new System.Drawing.Size(1063, 55);
label.TabIndex = 0;
label.Text = title;
label.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
label.BackColor = chart.BackColor;
chart.Dock = System.Windows.Forms.DockStyle.Fill;
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
tableLayoutPanel.AutoSize = true;
tableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
tableLayoutPanel.BackColor = System.Drawing.Color.White;
tableLayoutPanel.ColumnCount = 1;
tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 1069F));
tableLayoutPanel.Controls.Add(label, 0, 0);
tableLayoutPanel.Controls.Add(chart, 0, 1);
tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
tableLayoutPanel.Location = new System.Drawing.Point(0, 0);
tableLayoutPanel.Name = "tableLayoutPanel1";
tableLayoutPanel.RowCount = 2;
tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel.Size = new System.Drawing.Size(1069, 662);
tableLayoutPanel.TabIndex = 2;
return (tableLayoutPanel);
}
I have panels and each of them has 1 label. Everything works fine except 1 thing:
I can't fit the Panel Height to the Label Height...
I'm using this code:
Point location = new Point(0, 0);
ColorConverter cc = new ColorConverter();
foreach (var item in temp)
{
Panel pan = new Panel();
pan.AutoSize = false;
pan.Width = this.Width-75;
pan.Location = location;
pan.BackColor = (Color)cc.ConvertFromString("#" + item.Item3);
Label lbl = new Label();
lbl.Font = new Font("Arial", 12);
lbl.ForeColor = Color.White;
lbl.Text = item.Item2;
lbl.AutoSize = true;
lbl.MaximumSize = new Size(pan.Width - 5, 0);
lbl.Width = pan.Width - 10;
lbl.Location = new Point(lbl.Location.X + 5, lbl.Location.Y + 5);
//pan.Height = lbl.Height + 5;
pan.Controls.Add(lbl);
flowLayoutPanel1.Controls.Add(pan);
location = new Point(location.X - pan.Height, location.Y);
}
I tried doing this:
pan.Height = lbl.Height + 5;
But it the panel is then way too small...
It seems to me, that you are using a panel in order to get a margin around the label within the FlowLayoutPanel. If this is the case, set the Label's margin instead and don't use a Panel:
lbl.Margin = new Padding(5, 5, 80, 5);
or
lbl.Margin = new Padding(5); // If all margins are equal
the constructors are declared like this
public Padding(int left, int top, int right, int bottom)
public Padding(int all)
You could try docking the label in the panel, set the panel AutoSize to true and set AutoSizeMode to GrowAndShrink. Then you can set the panel padding to 5. That way you won't have to worry about the label size or location
foreach (var item in temp)
{
Panel pan = new Panel();
pan.Padding = new Padding(5);
pan.AutoSize = true;
pan.AutoSizeMode = AutoSizeMode.GrowAndShrink;
pan.BackColor = (Color)cc.ConvertFromString("#" + item.Item3);
Label lbl = new Label();
lbl.Dock = DockStyle.Fill;
lbl.Font = new Font("Arial", 12);
lbl.ForeColor = Color.White;
lbl.Text = item.Item2;
lbl.AutoSize = true;
lbl.MaximumSize = new Size(pan.Width - 5, 0);
pan.Controls.Add(lbl);
flowLayoutPanel1.Controls.Add(pan);
location = new Point(location.X - pan.Height, location.Y);
}
Edit : forgot the padding.
Why tableLayoutPanel.Dock = DockStyle.Fill; do not work and tableLayoutPanel does not fill all available space in Form?
How to scale button.Text = "Button";?
namespace Scalability
{
static class Program
{
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ViewForm viewForm = new ViewForm();
Application.Run(viewForm);
}
}
}
namespace Scalability.Forms
{
class ViewForm:Form
{
public ViewForm()
{
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
Button button = new Button();
button.Text = "Button";
button.Dock = DockStyle.Fill;
Label label = new Label();
label.Text="Label";
label.Dock = DockStyle.Fill;
TextBox textBox = new TextBox();
textBox.Text = "textBox";
textBox.Dock = DockStyle.Fill;
tableLayoutPanel.Controls.Add(button, 0, 0);
tableLayoutPanel.Controls.Add(label, 0, 1);
tableLayoutPanel.Controls.Add(textBox, 1, 0);
tableLayoutPanel.Dock = DockStyle.Fill;
this.Controls.Add(tableLayoutPanel);
}
}
}
configurate RowStyles of TableLayoutPanel to make them stretch
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50));
tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50));
But it does work. :)
1) Try to attach colors to your controls like this.
Button button = new Button();
button.Text = "Button";
button.BackColor = Color.Orange;
button.Dock = DockStyle.Fill;
Label label = new Label();
label.Text = "Label";
label.BackColor = Color.Yellow;
label.Dock = DockStyle.Fill;
TextBox textBox = new TextBox();
textBox.Text = "textBox";
textBox.BackColor = Color.Green;
textBox.Dock = DockStyle.Fill;
Now you will see that the controls use your entire window exactly in the way you put them. So button is col 0, row 0 (left, top). Textbox is col 1, row 0 (right, top). Label is col 0, row 1 (left bottom). And there is nothing in col 1 row 1 (right bottom "central place" is empty).
If you add a button to 1,1 it will stretch in the remaining space. Like this
// Blue button.
Button bbutton = new Button();
bbutton.Text = "Button";
bbutton.BackColor = Color.Blue;
bbutton.Dock = DockStyle.Fill;
tableLayoutPanel.Controls.Add(button, 0, 0);
tableLayoutPanel.Controls.Add(label, 0, 1);
tableLayoutPanel.Controls.Add(textBox, 1, 0);
// We added this one.
tableLayoutPanel.Controls.Add(bbutton, 1, 1);
tableLayoutPanel.Dock = DockStyle.Fill;
So there you have it.
I have a few tablelayoutpanels in my program in order to lay out different controls in rows. Until recently these were all working correctly, but after a change in server this is no longer the case. A potential cause is a change in screen resolution as I noticed similar problems on other computers running my program.
An example of this problem is shown below
Before the data rows are loaded (from database), the sizing is incorrect. A measurement using the VS designer shows that the size in figure 2 is correct. Interestingly, if I add a blank row to this table then the resizing doesn't happen.
public JobOpMainTable()
{
DoubleBuffered = true;
AutoSize = true;
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
DoubleBuffered = true;
BackColor = Color.White;
CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
headers();
}
private void headers()
{
string[] names = { "Operation", "Est Lab Hrs", "Est UM Hrs", "Act Lab Hrs", "Act UM Hrs" };
for (int i = 0; i < names.Length; i++) header(names[i], i);
}
private void header(string name, int col)
{
Panel pan = new Panel();
pan.Width = widths[col];
pan.Height = 25;
pan.BackColor = Color.Black;
pan.Dock = DockStyle.Fill;
pan.Margin = new System.Windows.Forms.Padding(0);
TextBox txt = new TextBox();
txt.Font = new System.Drawing.Font("Microsoft sans serif", 8, FontStyle.Bold);
txt.Text = name;
txt.ReadOnly = true;
txt.BackColor = Color.Black;
txt.ForeColor = Color.White;
txt.Dock = DockStyle.Fill;
txt.BorderStyle = System.Windows.Forms.BorderStyle.None
pan.Controls.Add(txt);
Controls.Add(pan, col, 0);
}
private int newRow()
{
int row = Controls.Count / 5;
for (int i = 0; i <= 4; i++)
{
TextBox txt = new TextBox();
txt.Width = widths[i];
txt.BackColor = Color.White;
txt.BorderStyle = System.Windows.Forms.BorderStyle.None;
txt.ReadOnly = true;
txt.Dock = DockStyle.Fill;
txt.Margin = new Padding(0);
txt.Enter += new EventHandler(enterCell);
txt.Leave += new EventHandler(leaveCell);
Controls.Add(txt, i, row);
}
return row;
}
Above is the code I believe is relevant to the problem. The resizing occurs the first time newRow() is called when loading in data: each new box makes the column wider. Again though, the odd thing is this doesn't occur if I add a row from the constructor