Создавайте динамически элементы управления в столбцах внутри панели - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть панель, где я создаю поля Labels и NumericUpDown, динамически похожие на:

        List<string> Labels = new List<string>();
        public List<Label> DeliveryBreakdownLabelsModel = new List<Label>();
        public List<NumericUpDown> DeliveryBreakdownNumericUpDownModel = new List<NumericUpDown>();


    private void SetDeliveryBreakdownAmountForm_Load(object sender, EventArgs e)
        {
           var rModel = //List data from database
            AddRow(rModel);
            Arrange();
        }




      private void AddRow(IList<DeliveryBreakdownGetViewModel> rModel)
        {
            for (int i = 0; i < rModel.Count; i++)
            {
                Labels.Add(rModel[i].DesignGroupName);
                var label = new Label
                {
                    AutoSize = true, // make sure to enable AutoSize
                    Name = "label" + Labels.Count,
                    Text = rModel[i].DesignGroupName,
                    Location = new Point(12, YPos)
                };
                this.Controls.Add(label);
                pnlDeliveryBreakdown.Controls.Add(label);
                DeliveryBreakdownLabelsModel.Add(label);


                var numericUpDown = new NumericUpDown
                {
                    Name = "numericUpDown" + Labels.Count,
                    Text = rModel[i].ContractedAmount.ToString(),
                    Location = new Point(12, YPos),
                    Size = new Size(60, 19),
                    DecimalPlaces = 2,
                    Maximum = decimal.MaxValue
                };
                this.Controls.Add(numericUpDown);
                this.Controls.Add(numericUpDown);
                pnlDeliveryBreakdown.Controls.Add(numericUpDown);
                DeliveryBreakdownNumericUpDownModel.Add(numericUpDown);


                YPos += 25;
            }
        }





         void Arrange()
        {
            // Determine the widest label sized by the AutoSize 
            var maxLabelX = 0;
            for (int i = 0; i < Labels.Count; i++)
            {
                maxLabelX = Math.Max(maxLabelX, DeliveryBreakdownLabelsModel[i].Location.X + DeliveryBreakdownLabelsModel[i].Size.Width);
            }

            // Move all the text boxes a little to the right of the widest label
            var maxNumericX = 0;
            for (int i = 0; i < Labels.Count; i++)
            {
                maxNumericX = Math.Max(maxNumericX, DeliveryBreakdownNumericUpDownModel[i].Location.X + DeliveryBreakdownNumericUpDownModel[i].Size.Width);
                DeliveryBreakdownNumericUpDownModel[i].Location = new Point(maxLabelX + 10, DeliveryBreakdownNumericUpDownModel[i].Location.Y);
            }

            //Set total wi
            this.Width = maxNumericX + maxLabelX + 60;
        }

Так это выглядит так:

enter image description here

Мой вопрос: как я могу изменить свой код, чтобы создать более одного столбца. Я хочу сделать это, потому что иногда у меня может быть много данных, поэтому показы только по вертикали могут стать проблемой в будущем. Ожидаемый результат: IE

enter image description here

1 Ответ

2 голосов
/ 25 февраля 2020

Я предлагаю использовать TableLayoutPanel с UserControl, который содержит ровно одну метку и одну цифру c.

Даже в конструкторе это выглядит аккуратно.

pic1

Все, что вам нужно сделать, это выставить нужные свойства из поля цифры 1025 в вашем пользовательском элементе управления.

В приведенном выше примере я используя следующий код:

// Fixed height user control
// Some code taken from: https://stackoverflow.com/a/4388922/380384
[Designer(typeof(MyControlDesigner))]
public partial class LabelNumeric : UserControl
{
    public LabelNumeric()
    {
        InitializeComponent();
    }

    protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
    {
        base.SetBoundsCore(x, y, width, 24, specified);
    }
    [DefaultValue("Label")]
    public string Caption
    {
        get => label1.Text;
        set => label1.Text = value;
    }
    [DefaultValue(0)]
    public decimal Value
    {
        get => numericUpDown1.Value;
        set => numericUpDown1.Value =value;
    }
    [DefaultValue(0)]
    public int DecimalPlaces
    {
        get => numericUpDown1.DecimalPlaces;
        set => numericUpDown1.DecimalPlaces = value;
    }
    [DefaultValue(100)]
    public decimal MaxValue
    {
        get => numericUpDown1.Maximum;
    }
    [DefaultValue(0)]
    public decimal MinValue
    {
        get => numericUpDown1.Minimum;
    }
}
internal class MyControlDesigner : ControlDesigner
{
    MyControlDesigner()
    {
        base.AutoResizeHandles = true;
    }
    public override SelectionRules SelectionRules
    {
        get
        {
            return SelectionRules.LeftSizeable | SelectionRules.RightSizeable | SelectionRules.Moveable;
        }
    }
}

Вы можете получить доступ ко всем элементам управления из свойства tableLayoutPanel1.Controls и проверить их положение в таблице следующим образом:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        foreach (var item in tableLayoutPanel1.Controls.OfType<LabelNumeric>())
        {
            var pos = tableLayoutPanel1.GetCellPosition(item);
            item.Caption = $"Row{pos.Row}Col{pos.Column}";
        }
    }
}

Таким образом, во время выполнения это следующим образом:

pic2

Хитрость заключается в том, чтобы иметь один дополнительный ряд в нижней части автоматически изменяемого размера, а все остальные строки, содержащие элементы управления, должны иметь фиксированную высоту 24pt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...