使用 TableLayoutPanel 创建相同大小的单元格
Creating same size cells with TableLayoutPanel
我正在尝试使用 C# 中的 TableLayoutPanel
来填写 Form
。 TableLayoutPanel
应该包含 10x10 面板,所有面板都具有相同的大小(按百分比)。
尽管我似乎无法让它为最后一行或最后一列工作。
allPanel.RowCount = 10;
allPanel.ColumnCount = 10;
allPanel.Padding = 10;
allPanel.BackColor = Color.Green;
allPanel.AutoSize = true;
allPanel.Dock = DockStyle.Fill;
allPanel.RowStyles.Clear();
allPanel.ColumnStyles.Clear();
windowsForm.Controls.Add(allPanel);
for (int i = 0; i < 10; i++) {
allPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 10));
}
for (int i = 0; i < 10; i++) {
allPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 10));
}
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
boardTiles[i, j] = new Panel();
boardTiles[i, j].BackColor = Color.White;
allPanel.Controls.Add(boardTiles[i, j], i, j);
}
}
结果如下:
我不喜欢 TableLayoutPanel。我可以用下面的代码实现同样的效果。 TableLayoutPanel 的属性数量有限,我经常发现我需要额外的属性。您可以继承任何 class(我使用按钮)。我将按钮放在窗体上,但您也可以将按钮放在标准面板上,这样面板就可以在窗体上移动,所有按钮也会一起移动。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Buttons
{
public partial class Form1 : Form
{
const int ROWS = 5;
const int COLS = 10;
public Form1()
{
InitializeComponent();
this.Load += new System.EventHandler(this.Form1_Load);
}
public void Form1_Load(object sender, EventArgs e)
{
new MyButton(ROWS, COLS, this);
}
}
public class MyButton : Button
{
const int WIDTH = 50;
const int HEIGHT = 50;
const int SPACE = 5;
const int BORDER = 20;
public static List<List<MyButton>> buttons { get; set; }
public static List<MyButton> buttonList { get; set; }
public Form1 form1;
public int row { get; set; }
public int col { get; set; }
public MyButton()
{
}
public MyButton(int rows, int cols, Form1 form1)
{
buttons = new List<List<MyButton>>();
buttonList = new List<MyButton>();
this.form1 = form1;
for(int row = 0; row < rows; row++)
{
List<MyButton> newRow = new List<MyButton>();
buttons.Add(newRow);
for (int col = 0; col < cols; col++)
{
MyButton newButton = new MyButton();
newButton.Height = HEIGHT;
newButton.Width = WIDTH;
newButton.Top = row * (HEIGHT + SPACE) + BORDER;
newButton.Left = col * (WIDTH + SPACE) + BORDER;
newButton.row = row;
newButton.col = col;
newRow.Add(newButton);
buttonList.Add(newButton);
newButton.Click += new System.EventHandler(Button_Click);
form1.Controls.Add(newButton);
}
}
}
public void Button_Click(object sender, EventArgs e)
{
MyButton button = sender as MyButton;
MessageBox.Show(string.Format("Pressed Button Row {0} Column {1}", button.row, button.col));
}
}
}
Cells
'的维度是integers
;因此,为了使布局正常工作,您需要确保 TLP
的净面积实际上 可被 整除 您希望它包含的单元格数。
净面积是 ClientSize
减去 Padding
。
因此,对于 10 的 Padding
,您需要 (n * w + 20, m * h + 20)
的 n x m
个单元格 Width w
] 和 Height h
.
因为你想填充一个容器,你需要:
- 控制容器大小以匹配公式
- 或计算
Padding
以便它更正整数除法错误
这是计算正确 Padding
:
的函数
Padding GetCorrectionPadding(TableLayoutPanel TLP, int minimumPadding)
{
int minPad = minimumPadding;
Rectangle netRect = TLP.ClientRectangle;
netRect.Inflate(-minPad, -minPad);
int w = netRect.Width / TLP.ColumnCount;
int h = netRect.Height / TLP.RowCount;
int deltaX = (netRect.Width - w * TLP.ColumnCount) / 2;
int deltaY = (netRect.Height - h * TLP.RowCount) / 2;
int OddX = (netRect.Width - w * TLP.ColumnCount) % 2;
int OddY = (netRect.Height - h * TLP.RowCount) % 2;
return new Padding(minPad + deltaX, minPad + deltaY,
minPad + deltaX + OddX, minPad + deltaY + OddY);
}
注意代码..
- 假设
TLP
已经填满
- 假定您想要的 最小值
Padding
的某个值。由于我们最多需要 n-1
像素来进行校正,因此水平和垂直填充可能相差 一半 ,在您的情况下最多 4 or 5
像素。
您可以这样称呼它:
allPanel.Padding = GetCorrectionPadding(allPanel, 5);
如果你想避免这种情况,你需要选择选项一,即确保容器有合适的尺寸!
当然,每次调整大小后都需要再次应用更正 Padding
..
我正在尝试使用 C# 中的 TableLayoutPanel
来填写 Form
。 TableLayoutPanel
应该包含 10x10 面板,所有面板都具有相同的大小(按百分比)。
尽管我似乎无法让它为最后一行或最后一列工作。
allPanel.RowCount = 10;
allPanel.ColumnCount = 10;
allPanel.Padding = 10;
allPanel.BackColor = Color.Green;
allPanel.AutoSize = true;
allPanel.Dock = DockStyle.Fill;
allPanel.RowStyles.Clear();
allPanel.ColumnStyles.Clear();
windowsForm.Controls.Add(allPanel);
for (int i = 0; i < 10; i++) {
allPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 10));
}
for (int i = 0; i < 10; i++) {
allPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 10));
}
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
boardTiles[i, j] = new Panel();
boardTiles[i, j].BackColor = Color.White;
allPanel.Controls.Add(boardTiles[i, j], i, j);
}
}
结果如下:
我不喜欢 TableLayoutPanel。我可以用下面的代码实现同样的效果。 TableLayoutPanel 的属性数量有限,我经常发现我需要额外的属性。您可以继承任何 class(我使用按钮)。我将按钮放在窗体上,但您也可以将按钮放在标准面板上,这样面板就可以在窗体上移动,所有按钮也会一起移动。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Buttons
{
public partial class Form1 : Form
{
const int ROWS = 5;
const int COLS = 10;
public Form1()
{
InitializeComponent();
this.Load += new System.EventHandler(this.Form1_Load);
}
public void Form1_Load(object sender, EventArgs e)
{
new MyButton(ROWS, COLS, this);
}
}
public class MyButton : Button
{
const int WIDTH = 50;
const int HEIGHT = 50;
const int SPACE = 5;
const int BORDER = 20;
public static List<List<MyButton>> buttons { get; set; }
public static List<MyButton> buttonList { get; set; }
public Form1 form1;
public int row { get; set; }
public int col { get; set; }
public MyButton()
{
}
public MyButton(int rows, int cols, Form1 form1)
{
buttons = new List<List<MyButton>>();
buttonList = new List<MyButton>();
this.form1 = form1;
for(int row = 0; row < rows; row++)
{
List<MyButton> newRow = new List<MyButton>();
buttons.Add(newRow);
for (int col = 0; col < cols; col++)
{
MyButton newButton = new MyButton();
newButton.Height = HEIGHT;
newButton.Width = WIDTH;
newButton.Top = row * (HEIGHT + SPACE) + BORDER;
newButton.Left = col * (WIDTH + SPACE) + BORDER;
newButton.row = row;
newButton.col = col;
newRow.Add(newButton);
buttonList.Add(newButton);
newButton.Click += new System.EventHandler(Button_Click);
form1.Controls.Add(newButton);
}
}
}
public void Button_Click(object sender, EventArgs e)
{
MyButton button = sender as MyButton;
MessageBox.Show(string.Format("Pressed Button Row {0} Column {1}", button.row, button.col));
}
}
}
Cells
'的维度是integers
;因此,为了使布局正常工作,您需要确保 TLP
的净面积实际上 可被 整除 您希望它包含的单元格数。
净面积是 ClientSize
减去 Padding
。
因此,对于 10 的 Padding
,您需要 (n * w + 20, m * h + 20)
的 n x m
个单元格 Width w
] 和 Height h
.
因为你想填充一个容器,你需要:
- 控制容器大小以匹配公式
- 或计算
Padding
以便它更正整数除法错误
这是计算正确 Padding
:
Padding GetCorrectionPadding(TableLayoutPanel TLP, int minimumPadding)
{
int minPad = minimumPadding;
Rectangle netRect = TLP.ClientRectangle;
netRect.Inflate(-minPad, -minPad);
int w = netRect.Width / TLP.ColumnCount;
int h = netRect.Height / TLP.RowCount;
int deltaX = (netRect.Width - w * TLP.ColumnCount) / 2;
int deltaY = (netRect.Height - h * TLP.RowCount) / 2;
int OddX = (netRect.Width - w * TLP.ColumnCount) % 2;
int OddY = (netRect.Height - h * TLP.RowCount) % 2;
return new Padding(minPad + deltaX, minPad + deltaY,
minPad + deltaX + OddX, minPad + deltaY + OddY);
}
注意代码..
- 假设
TLP
已经填满 - 假定您想要的 最小值
Padding
的某个值。由于我们最多需要n-1
像素来进行校正,因此水平和垂直填充可能相差 一半 ,在您的情况下最多4 or 5
像素。
您可以这样称呼它:
allPanel.Padding = GetCorrectionPadding(allPanel, 5);
如果你想避免这种情况,你需要选择选项一,即确保容器有合适的尺寸!
当然,每次调整大小后都需要再次应用更正 Padding
..