C# обрабатывает изменение размера динамически создаваемых графических полей

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



Кажется, это отлично работает, но проблема возникает, когда я увеличиваю размер приложения, тогда поля с изображениями не расширяются правильно, как на изображении ниже:


Увеличение приложения:

Уменьшение размера приложения:

Вот метод:

 private void CreatePictureBoxes(int num)
        {
            panelCameras.Controls.Clear();

            int spacing = 2;
            int numRows = (int)Math.Ceiling((double)num / 2);

            int pbWidth = (panelCameras.ClientSize.Width - (3 * spacing)) / 2;
            int pbHeight = (panelCameras.ClientSize.Height - ((numRows + 1) * spacing)) / numRows;

            if (num == 1)
            {
                pbWidth = panelCameras.ClientSize.Width - (2 * spacing);
                pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
            }
            else if (num == 2)
            {
                pbWidth = (panelCameras.ClientSize.Width - (2 * spacing)) / 2;
                pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
            }

            for (int i = 0; i < num; i++)
            {
                PictureBox pb = new PictureBox();
                pb.BackColor = Color.Black;
                pb.SizeMode = PictureBoxSizeMode.StretchImage;
                pb.Dock = DockStyle.None;
                pb.Anchor = AnchorStyles.None;
                pb.Location = new Point((i % 2) * (pbWidth + spacing) + spacing, (i / 2) * (pbHeight + spacing) + spacing);

                Label lbl = new Label();
                lbl.Text = (i + 1).ToString();
                lbl.ForeColor = Color.White;
                lbl.AutoSize = false;
                lbl.Dock = DockStyle.Fill;
                lbl.TextAlign = ContentAlignment.MiddleCenter;
                pb.Controls.Add(lbl);

                panelCameras.Controls.Add(pb);

                pb.Size = new Size(pbWidth, pbHeight);
                pb.Dock = DockStyle.None;
                pb.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;

                
            }
        }

Моя лучшая попытка исправить это состояла в том, чтобы создать дополнительный метод для обработки расширения приложения и вызывать его в конце конца метода CreatePictureBoxes:


private void pb_Resize(object sender, EventArgs e)
        {
            PictureBox? pb = sender as PictureBox ?? null;

            if (pb != null)
            {
                int spacing = 10;
                int numRows = (int)Math.Ceiling((double)panelCameras.Controls.Count / 2);

                int pbWidth = (panelCameras.ClientSize.Width - (3 * spacing)) / 2;
                int pbHeight = (panelCameras.ClientSize.Height - ((numRows + 1) * spacing)) / numRows;

                if (panelCameras.Controls.Count == 1)
                {
                    pbWidth = panelCameras.ClientSize.Width - (2 * spacing);
                    pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
                }
                else if (panelCameras.Controls.Count == 2)
                {
                    pbWidth = (panelCameras.ClientSize.Width - (2 * spacing)) / 2;
                    pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
                }

                pb.Size = new Size(pbWidth, pbHeight);
                pb.Location = new Point((pb.TabIndex % 2) * (pbWidth + spacing) + spacing, (pb.TabIndex / 2) * (pbHeight + spacing) + spacing);
            }
        }

Это каким-то образом сработало, но я считаю, что это вызовет больше проблем в будущем, и я не считаю, что это хороший подход.

Кто-нибудь знает, как я могу обрабатывать размеры изображений, чтобы они соответствовали размеру приложения?

Заранее спасибо!

Нет, используйте TableLayoutPanel, установите во время разработки SizeType столбцов и строк, чтобы они делили пространство поровну, состыкуйте поля в ячейках сетки 2x2, и все.

dr.null 19.04.2023 15:06

Спасибо @dr.null Будет ли то, что сказал Иржи в их ответе, подходящим ответом, или вы знаете лучшее решение?

Nicolantonio De Bari 19.04.2023 15:56

Принятый ответ является прямым решением проблемы, которую вы привели. Итак, это принято для меня. Однако вам не нужно делать это в первую очередь, элементы управления макетом WinForms существуют по какой-то причине, в основном для того, чтобы избежать того, что вы делаете здесь. Лучшим решением или правильным подходом является использование панели макета, в частности предложенной в моем первом комментарии.

dr.null 19.04.2023 16:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы разделил создание и раскладку панелей, вот так:

public Form1()
{
    InitializeComponent();

    // ...

    panelCameras.Layout += panelCameras_Layout;
}

private void CreatePictureBoxes(int num)
{
    panelCameras.Controls.Clear();

    for (int i = 0; i < num; i++)
    {
        PictureBox pb = new PictureBox();
        pb.BackColor = Color.Black;
        pb.SizeMode = PictureBoxSizeMode.StretchImage;
        pb.Dock = DockStyle.None;
        pb.Anchor = AnchorStyles.None;

        Label lbl = new Label();
        lbl.Text = (i + 1).ToString();
        lbl.ForeColor = Color.White;
        lbl.AutoSize = false;
        lbl.Dock = DockStyle.Fill;
        lbl.TextAlign = ContentAlignment.MiddleCenter;
        pb.Controls.Add(lbl);

        panelCameras.Controls.Add(pb);
    }
}

protected void panelCameras_Layout(object? sender, LayoutEventArgs levent)
{
    var num = panelCameras.Controls.Count;

    for (var i = 0; i < num; ++i)
    {
        int spacing = 2;
        int numRows = (int)Math.Ceiling((double)num / 2);

        int pbWidth = (panelCameras.ClientSize.Width - (3 * spacing)) / 2;
        int pbHeight = (panelCameras.ClientSize.Height - ((numRows + 1) * spacing)) / numRows;

        if (num == 1)
        {
            pbWidth = panelCameras.ClientSize.Width - (2 * spacing);
            pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
        }
        else if (num == 2)
        {
            pbWidth = (panelCameras.ClientSize.Width - (2 * spacing)) / 2;
            pbHeight = panelCameras.ClientSize.Height - (2 * spacing);
        }

        var pb = panelCameras.Controls[i];
        pb.Location = new Point((i % 2) * (pbWidth + spacing) + spacing, (i / 2) * (pbHeight + spacing) + spacing);
        pb.Size = new Size(pbWidth, pbHeight);
    }
}

Обратите внимание, что я удалил настройку размера и местоположения из CreatePictureBoxes, а также удалил изменение стиля привязки!

Спасибо! Я очень ценю помощь! Кажется, это работает отлично. У меня только один вопрос. Будет ли это правильным подходом к решению этой проблемы или вы поверите, что есть лучшая альтернатива?

Nicolantonio De Bari 19.04.2023 15:04

Это зависит. Обычно способов много, и выбрать один всегда сложно :), так что не волнуйтесь. Если вам нужно повторно использовать поведение, вы можете получить свой собственный элемент управления (скажем, из панели) и переопределить OnLayout. Часто вы понимаете, что решение уже существует — возможно, вы могли бы использовать TableLayoutPanel. Но если это работает хорошо для вас, используйте его. Вы всегда можете изменить его, если вам нужно.

Jiri Volejnik 19.04.2023 15:29

Другие вопросы по теме