我想创建一个布局管理器,它将面板划分为单元格,并且可以将一个组件添加到指定单元格(行、列)的面板中。重新调整面板大小时应更新单元格的宽度和高度(这是问题所在,它不会重新调整单元格的大小)。这些类本身可以工作,但是在调整大小时不会更新单元格大小,它甚至似乎都没有调用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;
}
}
}