在另一个面板中调整面板大小和定位面板

Resizing and positioning panels in another panel

我在另一个面板(此面板位于用户控件中)中为我的面板提供固定位置和最大尺寸,该尺寸随面板尺寸而变化。调整大小或位置均无法正常工作。调整大小确实发生了,但它很快。如果您只有 1 个 pinpanel 用于输出和输入,则该位置很好。当您有超过 1 个时,位置是固定的,但您需要调整面板大小以调整大小以查看其他面板。如果您看到问题,能否为我指出正确的方向?

在这种情况下,我有一个面板 drawPanel,用作用户控件的一种背景。在这个 drawPanel 中,我正在放置 pinpanels。我希望这些 pinpanels 调整用户控件的大小并给它们一个固定的位置

    private void OnClickPinPanel(object source, EventArgs e)
    {
        if (source is PinPanel p)
        {
            int index;
            if ((index = Array.IndexOf(inputPins, p)) >= 0)
            {
                ClickedPinPanel?.Invoke(index, true);
            }
            else
            {
                ClickedPinPanel?.Invoke(Array.IndexOf(outputPins, p), false);
            }
        }
        //else log here
    }

    private void CreatePinPanels(bool isInput)
    {
        int x = 0;
        int y = -(int)(this.Width * 0.05)/2;

        if (isInput)
        {
            for (int i = 0; i < inputPins.Length; i++)
            {
                y += (i + 1) * (this.Height / inputPins.Length + 1);
                inputPins[i] = new PinPanel()
                {
                    Location = new Point(x, y),
                    Size = new Size((int)(this.Width * 0.05), (int)(this.Width * 0.05)),
                    Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right,
                };
                inputPins[i].Click += OnClickPinPanel;
            }
        }
        else
        {
            x += this.Width - (int)(this.Width * 0.1);
            for (int i = 0; i < outputPins.Length; i++)
            {
                y += (i + 1) * (this.Height / inputPins.Length+1);
                outputPins[i] = new PinPanel()
                {
                    Size = new Size((int)(this.Width * 0.1), (int)(this.Width * 0.1)),
                    Location = new Point(x, y),
                    Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right
                };
                outputPins[i].Click += OnClickPinPanel;
            }
        }
    }

我现在得到的结果是 pinpanels 有一个固定的位置,但是当你有超过 1 个 pinpanel 时,这个位置是错误的,就像他认为用户控件更大然后它是 Reality. In order to see all the pins i have to resize and get this After resize

我希望它看起来像这样 expectations

试试这样的东西。

这是我的测试装置:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        numericUpDown1.Value = someChip1.NumberInputPins;
        numericUpDown2.Value = someChip1.NumberOutputPins;
    }

    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        someChip1.NumberInputPins = (int)numericUpDown1.Value;
    }

    private void numericUpDown2_ValueChanged(object sender, EventArgs e)
    {
        someChip1.NumberOutputPins = (int)numericUpDown2.Value;
    }

}

具有 5 个输入和 3 个输出的示例芯片:

这是我的 PinPanel UserControl(只是画了一个 ellipse/pin 大小的控件):

public partial class PinPanel : UserControl
{

    public PinPanel()
    {
        InitializeComponent();
    }

    private void PinPanel_Paint(object sender, PaintEventArgs e)
    {
        Rectangle rc = new Rectangle(new Point(0, 0), new Size(this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1));
        e.Graphics.DrawEllipse(Pens.Black, rc);
    }

    private void PinPanel_SizeChanged(object sender, EventArgs e)
    {
        this.Refresh();
    }

}

最后,我的 SomeChip 用户控件:

public partial class SomeChip : UserControl
{

    public event PinPanelClick ClickedPinPanel;
    public delegate void PinPanelClick(int index, bool input);

    private PinPanel[] inputPins;
    private PinPanel[] outputPins;

    private int _NumberInputPins = 2;
    public int NumberInputPins
    {
        get {
            return _NumberInputPins;
        }
        set
        {
            if (value > 0 && value != _NumberInputPins)
            {
                _NumberInputPins = value;
                CreatePinPanels();
                this.Refresh();
            }
        }
    }

    private int _NumberOutputPins = 1;
    public int NumberOutputPins
    {
        get
        {
            return _NumberOutputPins;
        }
        set
        {
            if (value > 0 && value != _NumberOutputPins)
            {
                _NumberOutputPins = value;
                CreatePinPanels();
                this.Refresh();
            }
        }
    }

    public SomeChip()
    {
        InitializeComponent();
    }

    private void SomeChip_Load(object sender, EventArgs e)
    {
        CreatePinPanels();
        RepositionPins();
    }

    private void SomeChip_SizeChanged(object sender, EventArgs e)
    {
        this.Refresh();
    }

    private void SomeChip_Paint(object sender, PaintEventArgs e)
    {
        int PinHeight;
        // draw the input pin runs
        if (inputPins != null)
        {
            PinHeight = (int)((double)this.Height / (double)_NumberInputPins);
            for (int i = 0; i < NumberInputPins; i++)
            {
                int Y = (i * PinHeight) + (PinHeight / 2);
                e.Graphics.DrawLine(Pens.Black, 0, Y, this.Width / 4, Y);
            }
        }
        // draw the output pin runs
        if (outputPins != null)
        {
            PinHeight = (int)((double)this.Height / (double)_NumberOutputPins);
            for (int i = 0; i < NumberOutputPins; i++)
            {
                int Y = (i * PinHeight) + (PinHeight / 2);
                e.Graphics.DrawLine(Pens.Black, this.Width - this.Width / 4, Y, this.Width, Y);
            }
        }
        //draw the chip itself (takes up 50% of the width of the UserControl)
        Rectangle rc = new Rectangle(new Point(this.Width / 4, 0), new Size(this.Width / 2, this.Height - 1));
        using (SolidBrush sb = new SolidBrush(this.BackColor))
        {
            e.Graphics.FillRectangle(sb, rc);
        }
        e.Graphics.DrawRectangle(Pens.Black, rc);
        RepositionPins();
    }

    private void CreatePinPanels()
    {
        if (inputPins != null)
        {
            for (int i = 0; i < inputPins.Length; i++)
            {
                if (inputPins[i] != null && !inputPins[i].IsDisposed)
                {
                    inputPins[i].Dispose();
                }
            }
        }
        inputPins = new PinPanel[_NumberInputPins];
        for (int i = 0; i < inputPins.Length; i++)
        {
            inputPins[i] = new PinPanel();
            inputPins[i].Click += OnClickPinPanel;
            this.Controls.Add(inputPins[i]);
        }
        if (outputPins != null)
        {
            for (int i = 0; i < outputPins.Length; i++)
            {
                if (outputPins[i] != null && !outputPins[i].IsDisposed)
                {
                    outputPins[i].Dispose();
                }
            }
        }
        outputPins = new PinPanel[_NumberOutputPins];
        for (int i = 0; i < outputPins.Length; i++)
        {
            outputPins[i] = new PinPanel();
            outputPins[i].Click += OnClickPinPanel;
            this.Controls.Add(outputPins[i]);
        }
    }

    private void OnClickPinPanel(object sender, EventArgs e)
    {
        PinPanel p = (PinPanel)sender;
        if (inputPins.Contains(p))
        {
            ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), true);
        }
        else if (outputPins.Contains(p))
        {
            ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), false);
        }
    }

    private void RepositionPins()
    {
        int PinRowHeight, PinHeight;
        if (inputPins != null)
        {
            PinRowHeight = (int)((double)this.Height / (double)_NumberInputPins);
            PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
            for (int i = 0; i < inputPins.Length; i++)
            {
                if (inputPins[i] != null && !inputPins[i].IsDisposed)
                {
                    inputPins[i].SetBounds(0, (int)((i * PinRowHeight) + (PinRowHeight /2 ) - (PinHeight / 2)), PinHeight, PinHeight);
                }
            }
        }
        if (outputPins != null)
        {
            PinRowHeight = (int)((double)this.Height / (double)_NumberOutputPins);
            PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
            for (int i = 0; i < outputPins.Length; i++)
            {
                if (outputPins[i] != null && !outputPins[i].IsDisposed)
                {
                    outputPins[i].SetBounds(this.Width - PinHeight, (int)((i * PinRowHeight) + (PinRowHeight / 2) - (PinHeight / 2)), PinHeight, PinHeight);
                }
            }
        }
    }

}