3

パネルをセルに分割するレイアウト マネージャーを作成したいのですが、セル (行、列) を指定してコンポーネントをパネルに追加できます。パネルのサイズ変更時にセルの幅と高さを更新する必要があります (これが問題で、セルのサイズは変更されません)。クラス自体は機能しますが、サイズを変更してもセルのサイズが更新されず、 を呼び出しているようにも見えませんLayoutManager::SetBounds(int, int)。別のクラスを作成する理由は、同じ Layout Manager を他のコンテナー (たとえば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;
        }
    }
}
4

1 に答える 1

0

TableLayoutPanel クラスをご覧ください。このコントロールはまさにあなたが達成しようとしていることだと思います。TableLayoutPanel を使用すると、フォーム エディターで行/列を定義し、プログラムでセル内にコントロールを配置したり、行/列を結合したり、コンテンツに応じてパネルを自動サイズ調整したり、パネル サイズに応じてコンテンツを自動サイズ調整したりできます。

Windowsフォームでレイアウトがどのように機能するかについての非常に興味深いドキュメントがあります:

https://docs.google.com/viewer?a=v&q=cache:nePz-uaPReYJ:www.windowsclient.net/samples/go%2520to%2520market/layout/layoutgtm.doc+Whidbey+Layout+tablelayoutpanel&hl=de&gl= de&pid=bl&srcid=ADGEEShlobh-RfSTegC1NuOc72m0vRPu6RsF3USTSPnSasU-9qSklTbJzclRol6Nxg5sxEUXZOWYZwgrSdZdAjJ5EXhCft7qj5jBr4-kkkX6380-0itVaHkG-TAvK4KvNtDymEFlUXM6&sig=AHIEtbTnyasKOG5tuZwub59LBw8UeZL8Lg

残念ながら、Google 検索キャッシュでしかドキュメントを見つけることができませんでした。元のリンクは削除されているようです。

于 2012-11-10T11:18:06.230 に答える