Как указать локализацию кнопок и как правильно создать событие удалить и передать на динамически созданные кнопки?

При нажатии на кнопку btn_scrennshot_Click создается динамический picturebox и еще 2 кнопки btn_exort_to_panel2 и btn_deletethispb, на Picturebox видно только одну кнопку слева сверху, вторая не отображается, как указать локализации кнопок в Picturebox, и как можно создать событие на btn_exort_to_panel2 отправить этот Picture box в flowLayoutPanel_images.

А на кнопку btn_deletethispb - удалить этот Picturebox со всеми кнопками, изображениями и тектовыми данными? Заранее благодарю!

private void btn_scrennshot_Click(object sender, EventArgs e)
    {
        
        var pb = new PictureBox();

        var name = new Label();

        var btn_deletethispb = new Button();

        var btn_exort_to_panel2 = new Button();
        
        try
        {
            Mat m = new Mat();

            capture.Retrieve(m);

            pb.Image = m.ToImage<Bgr, byte>().Flip(Emgu.CV.CvEnum.FlipType.None).Bitmap;

            pb.SizeMode = PictureBoxSizeMode.Zoom;

            pb.Height = pb.Image.Height / 2;

            pb.Width = pb.Image.Width / 2;                

            name.Text = $"SMV_{textBox_surename.Text + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second}";

            flowLayoutPanel1.Controls.Add(pb);                

            flowLayoutPanel1.Controls.Add(name);

            pb.Controls.Add(btn_exort_to_panel2);

            btn_exort_to_panel2.Text = "Выбрать";

            pb.Controls.Add(btn_deletethispb);

            btn_deletethispb.Text = "Удалить";                
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

Я дилетант, поэтому заранее прошу прощения если тут грубые ошибки в коде...


Ответы (1 шт):

Автор решения: Alexander Petrov

Видно только одну кнопку, потому что обеим назначены одни и те же координаты: 0, 0 по умолчанию. Первая кнопка получается спрятана под второй.

Чтобы не назначать вручную координаты контролам, проще взять ещё один контейнер наподобие TableLayoutPanel. Т. к. контролы сгруппированы в этом контейнере, позволит легко манипулировать ими всеми сразу.

Я набросал законченный пример програмы. Исправил нейминг.
В демонстрационных целях используется одна из системных иконок в качестве изображения.

В событиях кнопок находим их родителя и работаем с ним.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WinForm
{
    public partial class Form1 : Form
    {
        FlowLayoutPanel flowLayoutPanel1;
        FlowLayoutPanel flowLayoutPanelImages;
        TextBox surenameTextBox;
        Button screenshotButton;

        public Form1()
        {
            //InitializeComponent();

            this.WindowState = FormWindowState.Maximized;

            flowLayoutPanel1 = new FlowLayoutPanel { Parent = this, Dock = DockStyle.Left, Width = 500, BorderStyle = BorderStyle.FixedSingle };
            flowLayoutPanelImages = new FlowLayoutPanel { Parent = this, Dock = DockStyle.Right, Width = 500, BorderStyle = BorderStyle.FixedSingle };

            surenameTextBox = new TextBox { Parent = this, Text = "Info_", Left = 800 };

            screenshotButton = new Button { Parent = this, Left = 800, Top = 50, Text = "Shot" };
            screenshotButton.Click += ScreenshotButton_Click;
        }

        private void ScreenshotButton_Click(object sender, EventArgs e)
        {
            try
            {
                var panel = new TableLayoutPanel();
                panel.AutoSize = true;

                //Mat m = new Mat();
                //capture.Retrieve(m);

                var pb = new PictureBox();
                pb.Image = new Bitmap(SystemIcons.Shield.ToBitmap(), 256, 256); // m.ToImage<Bgr, byte>().Flip(Emgu.CV.CvEnum.FlipType.None).Bitmap;
                pb.SizeMode = PictureBoxSizeMode.Zoom;
                pb.Height = pb.Image.Height / 2;
                pb.Width = pb.Image.Width / 2;

                var nameLabel = new Label();
                nameLabel.Text = $"SMV_{surenameTextBox.Text}{DateTime.Now:HHmmss}";

                var exportButton = new Button();
                exportButton.Text = "Выбрать";
                exportButton.Click += ExportButton_Click;

                var deleteButton = new Button();
                deleteButton.Text = "Удалить";
                deleteButton.Click += DeleteButton_Click;

                panel.Controls.Add(pb);
                panel.Controls.Add(nameLabel);
                panel.Controls.Add(exportButton);
                panel.Controls.Add(deleteButton);

                flowLayoutPanel1.Controls.Add(panel);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ExportButton_Click(object sender, EventArgs e)
        {
            var exportButton = (Button)sender;
            var tableLayoutPanel = exportButton.Parent;
            tableLayoutPanel.Controls.Remove(exportButton);
            flowLayoutPanelImages.Controls.Add(tableLayoutPanel);

            exportButton.Dispose();
        }

        private void DeleteButton_Click(object sender, EventArgs e)
        {
            var deleteButton = (Button)sender;
            var tableLayoutPanel = deleteButton.Parent;
            var flowLayoutPanel = tableLayoutPanel.Parent;
            flowLayoutPanel.Controls.Remove(tableLayoutPanel);

            foreach (Control control in tableLayoutPanel.Controls)
                control.Dispose();

            tableLayoutPanel.Dispose();
        }
    }
}

Важно освобождать занятые ресурсы. Поэтому при удалении контролов диспозим их.

→ Ссылка