我想创建一个布局管理器,可以将面板分成多个单元格,用户可以通过指定单元格(行,列)来向该面板添加组件。当重新调整面板大小时,应更新单元格的宽度和高度(这是问题所在,它不会重新调整单元格的大小)。这些类本身是可用的,但是调整大小时它不会更新单元格的大小,甚至似乎没有调用LayoutManager::SetBounds(int, int)
。我之所以要创建一个单独的类,是因为我打算在其他容器中使用相同的布局管理器,例如GroupBox
。以下是我的代码:
public class Insets
{
public int bottom = 0;
public int top = 0;
public int left = 0;
public int right = 0;
public Insets(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
}
/*
* LayoutManager class
*/
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
public class LayoutManager
{
public enum Constraints{
HORIZONTAL,
VERTICAL,
NONE
};
public Insets insets = new Insets(0, 0, 0, 0);
public Constraints fill = Constraints.NONE;
public Panel container = null;
public int cellheight = 1;
public int cellwidth = 1;
private List <int> indices = new List <int>();
private int columns = 1;
private int rows = 1;
private int dh = 0;
private int dw = 0;
public LayoutManager(){
}
private int Index2DTo1D(int row, int column){
return (column + (row * columns));
}
private int Index1DToRow2D(int index){
return index / columns;
}
private int Index1DToColumn2D(int index){
return index / rows;
}
private void SetGridMatrix(int rows, int columns) {
if (rows >= this.rows){
this.rows = rows + 1;
}
if (columns >= this.columns){
this.columns = columns + 1;
}
}
public void RepaintChildrenComponents() {
if(container != null){
foreach(Control control in container.Controls){
((CheckBox)control).Text = container.Width.ToString();
}
}
}
public void SetBounds(int width, int height) {
SetCellsDimensions(width, height);
RepaintChildrenComponents();
}
public void SetCellsDimensions(int width, int height){
this.dw = width / columns;
this.dh = height / rows;
}
public void SetContainer(ref Panel container) {
this.container = container;
}
public Point GetChildComponentXY(int x, int y){
if(x >= 0 && y >= 0){
return new Point((x * dw) + insets.right, (y * dh) + insets.top);
}
throw new System.ArgumentOutOfRangeException("");
}
public Size GetComputedComponentSize(){
return new Size((cellwidth * dw) - (insets.left + insets.right),
(cellheight * dh) - (insets.top + insets.bottom));
}
public void AddComponent(Control control, Point location, LayoutManager.Constraints fill){
if(container != null && control != null){
indices.Insert(container.Controls.Count, Index2DTo1D(location.X, location.Y));
container.Controls.Add(SetChildComponentBounds(control, location));
SetGridMatrix(location.X, location.Y);
SetCellsDimensions(container.Width, container.Height);
}else{
throw new NullReferenceException("");
}
}
protected Control SetChildComponentBounds(Control control, Point location) {
control.Location = GetChildComponentXY(location.X, location.Y);
control.Size = GetComputedComponentSize();
return control;
}
public void AddComponent(Control control, Point location){
AddComponent(control, location, LayoutManager.Constraints.NONE);
}
}
/*
*
* JPanel class
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
class JPanel : Panel
{
private LayoutManager layman;
public JPanel(){
layman = new JComponent.LayoutManager();
Panel container = this;
layman.SetContainer(ref container);
string[] elems = { "Multiplication", "Division", "Addition", "Subtraction"};
int e = 0;
this.Size = new Size(300, 125);
foreach(string str in elems){
CheckBox box = new CheckBox();
box.Text = str;
layman.AddComponent(box, new Point(0, e++));
//this.Controls.Add(box);
}
}
public JPanel(LayoutManager layman) {
LayoutManager = layman;
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified){
if(layman != null){
layman.SetBounds(width, height);
}
base.SetBoundsCore(x, y, width, height, specified);
}
public LayoutManager LayoutManager{
set{
layman = value;
}
get{
return layman;
}
}
}