[C #] Controls added dynamically in the source ―― 1. Add click event to the button added dynamically

I want to dynamically add controls to a form and use them

C # article

-Use MySQL in C #-- 1. Development environment installation -Use MySQL in C #-- 2. SELECT / screen display -Use MySQL in C #-- 3. Additions and removals -Determining whether database data is NULL in C # -C # delegate and => (lambda expression) are treated like pointers to C functions --Dynamic addition of controls --1 Click button [This article] -Dynamic add control-- 2. Browse textbox

Usually when you click a button or browse a textbox

  1. Paste buttons and text boxes on the form in advance
  2. Define a click event method for the pre-pasted button
  3. When referencing the text box in any event, refer to the name of the pre-pasted text box.

In most cases, there are times when you want to flexibly set up controls dynamically according to the contents of master data and configuration files. For example, depending on the customer who is the user, it is common to a certain industry. When using the program, I think that some functions are necessary and some are not. However, ** customizing the program requires the effort required for customization **, so customization will be minimal for large companies, but Rilapo ♥ ︎ is C # only for large companies nationwide. There is no idea to benefit from it, ** Using Qiita on the premise that we can provide C # programs to a large number of customers in order to benefit from C # for large local companies, SMEs and private shops. That's why **, so naturally, the number of customers we deal with will increase overwhelmingly. When that happens, the sun goes down when it comes to customizing the program every time for a tremendous number of customers. .. .. (⑉ • ̆ · ̭ • ⑉)

That's why you can dynamically add controls and use them in master files, config files, etc. without having to mess with the C # source code. ?? First of all, I tried to find out at the level of how to implement it (˶ ・ ᴗ ・) ੭⚐⚑

I haven't used the database or config file yet this time, but I'll just mention how to describe the infrastructure to be implemented.

How to implement it dynamically? ??

--Create an instance of the control's object in the C # source --Set various properties on the control instance --Add that instance to the form and it will appear on the screen ――This alone is useless, so you need to give some event or make it identifiable so that it can be referenced.

In this way, you can write source code and add controls dynamically without using form design. It's quicker to use form design just to add it. .. ..

Try adding a control to the button dynamically

Start by only dynamically adding the button from the source code

If you want to add a control dynamically, simply adding the control is of course useless, so you need to add an action such as a click event dynamically, but ... But in the source code, specify the method again manually. I have to give it a try, so even if I try it all at once, it gets confusing, so ** first try how to dynamically add controls from the source **

フォームデザイン For the time being, set only the button "* formCallButton *" on the form, set the click event to the added button, and dynamically add the button to the left of the form during the click event processing. I tried it.

Form1.cs


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

namespace MyTrainingCsFrm1
{
    public partial class Form1 : Form
    {
        //Button to create by calling form
        private Button[] manyButtons;

        public Form1()
        {
            InitializeComponent();
            this.manyButtons = null;
        }

        //Button to call form
        private void formCallButton_Click(object sender, EventArgs e)
        {
            if (this.manyButtons != null)
            {
                MessageBox.Show("The form is already displayed");
                return;
            }
            
            //Button instantiation(Five)
            this.manyButtons = new Button[5];
            for (int i = 0; i < this.manyButtons.Length; i++)
            {
                this.manyButtons[i] = new Button();

                //Control properties
                this.manyButtons[i].Name = "OriginalButton" + i;
                this.manyButtons[i].Text = "button" + i;
                this.manyButtons[i].Location = new Point(10, 10 + i * 22);
                this.manyButtons[i].Size = new Size(80, 20);

                //Add to form
                this.Controls.Add(this.manyButtons[i]);
            }
        }
    }
}

First, prepare a dynamically created button as a member variable in an array in the form.

private Button[] manyButtons;

Next, since the dynamically created button is an array, we need to create an instance of the array itself and the buttons of each element.

this.manyButtons = new Button[5];
this.manyButtons[i] = new Button();

Up to this point, it is object-oriented and common. Next, set properties such as Name and placement for the button instance.

this.manyButtons[i].Name = "OriginalButton" + i;
this.manyButtons[i].Text = "button" + i;
this.manyButtons[i].Location = new Point(10, 10 + i * 22);
this.manyButtons[i].Size = new Size(80, 20);

Then, this code will be displayed on the form (˶ ・ ᴗ ・) ੭

this.Controls.Add(this.manyButtons[i]);

実行結果

It was displayed properly! !! (\ * ˘꒳˘ \ *)

Give an event to a dynamically added button

Now that we've created the button dynamically, let's add an event to that button! Next, add a list box called "listBox1" at the bottom right of the form to add the result of clicking the dynamically added button. I changed my mind a little about the button image (˶˙ᵕ˙˶)

フォームデザイン

Form1.cs


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

namespace MyTrainingCsFrm1
{
    public partial class Form1 : Form
    {
        //Button to create by calling form(Windows Forms Buttons-Inherit Button)
        private Kazumi75Button[] manyButtons;

        //Number of elements in the array(5 here)
        private const int ElementNum = 5;

        public Form1()
        {
            InitializeComponent();
            this.manyButtons = null;
        }

        //Button to call form
        private void formCallButton_Click(object sender, EventArgs e)
        {
            if (this.manyButtons != null)
            {
                MessageBox.Show("The form is already displayed");
                return;
            }

            //Each button message is preset here
            string[] msgs = new string[ElementNum];
            msgs[0] = "Uraga";
            msgs[1] = "Kamakura";
            msgs[2] = "Misaki";
            msgs[3] = "Kannonzaki";
            msgs[4] = "Yokosuka Chuo";
            

            //Creating a button(Inherit Windows Forms Buttons)
            this.manyButtons = new Kazumi75Button[ElementNum];
            for (int i = 0; i < this.manyButtons.Length; i++)
            {
                //Instance creation
                this.manyButtons[i] = new Kazumi75Button();
                
                //Set name and text properties
                this.manyButtons[i].Name = "OriginalButton" + i;
                this.manyButtons[i].Text = "button" + i;

                //Specify the list box to be referenced when the button is clicked
                this.manyButtons[i].targetLbox = listBox1;

                //Set message
                this.manyButtons[i].buttonMsg = msgs[i];

                //Size and placement
                this.manyButtons[i].Size = new Size(100, 20);
                this.manyButtons[i].Location = new Point(10, 10 + i * 22);

                //Add to form
                this.Controls.Add(this.manyButtons[i]);

                //Create an event behavior for each button on click
                this.manyButtons[i].eventMaking();
            }
        }
    }
}

Kazumi75Button.cs


using System;
using System.Windows.Forms;

namespace MyTrainingCsFrm1
{
    //Define the original button(Inherit Windows Forms Button)
    public class Kazumi75Button : Button
    {
        //Wording text displayed by pressing a button
        public string buttonMsg { get; set; }

        //Refer to the list box
        public ListBox targetLbox { get; set; }

        //Set an event for the button
        public void eventMaking()
        {
            this.Click += new EventHandler(doClickEvent);
        }

        //Cancel the event to the button
        public void eventSuspend()
        {
            this.Click -= new EventHandler(doClickEvent);
        }

        //The substance of the click event(Add text to the referenced list box)
        public void doClickEvent(object sender, EventArgs e)
        {
            this.targetLbox.Items.Add(this.buttonMsg);
        }
    }
}

Here, we are creating a button class called Kazumi75Button, which inherits from ** button Button. ** This is because the character string prepared for each button is used in the button click event when the button is clicked. In addition, the button body needs to be responsible for the listbox to be referenced so that it can reference listBox1 to display the results. It's pretty hard to say ... (੭ ु˙꒳˙) ੭ु Should I have a click event in Form1.cs? ?? Where it is a little difficult to judge. .. ..

private Kazumi75Button[] manyButtons;
private const int ElementNum = 5;
 …(Omission)…
this.manyButtons = new Kazumi75Button[ElementNum];

This first defines 5 arrays of Kazumi75Buttons that inherit the Windows Forms buttons. Now we will dynamically create 5 buttons and give them click events

this.manyButtons[i] = new Kazumi75Button();

I created an instance here, and after that, I set properties (don't forget to refer to listBox1) and place it on the form like Button. So, this time's point! !! First, array assignment processing before creating an instance

string[] msgs = new string[ElementNum];
msgs[0] = "Uraga";
msgs[1] = "Kamakura";
msgs[2] = "Misaki";
msgs[3] = "Kannonzaki";
msgs[4] = "Yokosuka Chuo";
 …(Omission)…
this.manyButtons[i].buttonMsg = msgs[i];

This is the string used when setting the string for each button with "* this.manyButtons [i] .buttonMsg = msgs [i] *", which is currently in the program source, but that part will be in the future It is supposed to be replaced with a database or configuration file. These strings are used in the button click event. next,

this.manyButtons[i].eventMaking();   // Form1.cs
public void eventMaking()            // Kazumi75Button.cs
{
    this.Click += new EventHandler(doClickEvent);
}
//The substance of the click event(Add text to the referenced list box)
public void doClickEvent(object sender, EventArgs e)
{
    this.targetLbox.Items.Add(this.buttonMsg);
}

A place where a click event is added to a dynamically defined button, and a character string for each button is added to listBox1 which displays the result when clicked.

It's become a bit complicated. .. .. (\ * ´꒳` \ *;) I'm sorry

実行結果

As for the execution result, the character string for each button is properly added to the form at the bottom right (˶ ・ ᴗ ・) ੭⚐

Try increasing the number of buttons

This time it is programmatic, but this time increase the number of elements from 5 to 8 and check if the number of buttons dynamically increases and the event also responds

Form1.Corrected part of cs


//Number of elements in the array(8 here)
private const int ElementNum = 8;

 …(Omission)…

string[] msgs = new string[ElementNum];
msgs[0] = "Uraga";
msgs[1] = "Kamakura";
msgs[2] = "Misaki";
msgs[3] = "Kannonzaki";
msgs[4] = "Yokosuka Chuo";
msgs[5] = "Jogashima";
msgs[6] = "Shichirigahama";
msgs[7] = "Umahori";

実行結果

Since "Jogashima", "Shichirigahama" and "Mabori" were added, they also displayed properly.

next time

Now that we've added all the buttons dynamically, let's add textboxes dynamically and see how to reference them dynamically ♡

References

-[.NET] Create control at runtime -[.NET] Dynamically register events -[Getting a control from a string representing the control name-Accessing the control from the string type of the string name-C # programming](https://www.ipentec.com/document/csharp-get-control-by- name-of-control-string) -Add an event to a (dynamic) control generated from a C # _ program -Control.ControlCollection.Find (String, Boolean) method --Microsoft .NET Official -How to search for controls on Windows Forms? [2.0 or later, C #, VB] --atmark IT

Recommended Posts